I have two lists, and I have a specific logic task that I'm not sure how to implement. Here are the lists:
list_1 = [826, 829, 830, 834, 837, 838, 842, 845, 846, 850]
list_2 = [826, 834, 842, 850]
list_2 is a subset of list_1.
The task I need is to make a list_3 using only the values in list_1 that precede the values in list_2. So it would be the list_1 items preceding 834, 842, and 850 (skipping 826 since nothing precedes it):
# Thus, we would end up with:
list_3 = [830, 838, 846]
This is a bit of a specific logic question if anyone has the chops to help me out. Much appreciated!
CodePudding user response:
lists in python can be searched as sets as well, so you don't have to worry about n^2 duration.
list_3 = [list_1[i - 1] for i in range(1, list_1) if list_1[i] in list_2 and list_1[i - 1] not in list_2]
or
list_3 = [list_1[i - 1] for i in range(1, list_1) if list_1[i] in list_2]
if you dont care that the previous item could be in list_2 also.
CodePudding user response:
if they're in the same order, you can solve it in one pass using two pointers, like
j = 0
list_3 = []
for i in range(len(list_1)):
if list_1[i]==list_2[j]:
if i>0:
list_3.append(list_1[i-1])
j = 1
CodePudding user response:
You could start with for item in list_2
to work with every elements form list_2
separately, and use list_1.index(item)
to get its position on other list, and put on list_3
item list_1[position-1]
if position-1 >= 0
(or if position > 0
)
list_1 = [826, 829, 830, 834, 837, 838, 842, 845, 846, 850]
list_2 = [826, 834, 842, 850]
list_3 = []
for item in list_2:
position = list_1.index(item)
if position > 0: # if position-1 >= 0:
predecessor = list_1[position-1]
list_3.append(predecessor)
print(predecessor)
CodePudding user response:
If there is no repeted elements in list_1:
list_1 = [826, 829, 830, 834, 837, 838, 842, 845, 846, 850]
list_2 = [826, 834, 842, 850]
list_idx = [list_1.index(x) - 1 for x in list_2]
list_idx = list(filter(lambda x: x >= 0, list_idx))
list_3 = [list_1[x] for x in list_idx]
If list_1 can have repeted elements:
list_idx = [
idx - 1 for idx, value in enumerate(list_1) for item2 in list_2 if value == item2
]
list_idx = list(filter(lambda x: x >= 0, list_idx))
list_3 = [list_1[x] for x in list_idx]
CodePudding user response:
Assuming that you have unique items in list_1, you can use a dictionary to map the previous values. The complexity is O(n)
:
d = dict(zip(list_1[1:], list_1))
list_3 = [d[x] for x in list_2 if x in d]
Output: [830, 838, 846]
Intermediate d
:
{829: 826, 830: 829, 834: 830, 837: 834, 838: 837, 842: 838, 845: 842, 846: 845, 850: 846}
NB. If you can have duplicates in list_1
, then it is possible to generalize by using a dictionary of lists, but the expected behavior should be defined.