根据另一个列表中的出现将项目附加到列表中

时间:2018-04-11 14:29:23

标签: python list loops append

所以我有一个清单:

my_list1 = ["p1", "p2", "p4", "p1"]

我还有另一个包含子列表的列表:

my_list2 = [[1,"p1"], [1,"p2"], [1,"p3"], [1,"p4"], [2, "p1"], [2, "p2"], [2, "p3"], [2, "p4"]]

现在我要做的是以下内容: 我想迭代my_list1然后再遍历my_list2并创建一个新列表,其中包含my_list1my_list2的每个元素的下一个出现。

即。我想要获得的是:

new_list = [[1, "p1"], [1, "p2"], [1, "p4"], [2, "p1"]]

我已经尝试了以下方法:

    new_list = []
    for i in my_list1:
        for j in my_list2:
            if i in j[1]:
                new_list.append(j)

哪个给了我

new_list = [[1,"p1"], [1,"p2"], [1,"p4"], [2, "p1"], [2, "p2"],  [2, "p4"]]

所以,我需要的是,每次迭代只追加my_list2中项目的下一个出现。

我是Python的新手,所以请保持温和。我非常感谢任何建议!

4 个答案:

答案 0 :(得分:3)

您的代码存在一些问题,但逻辑基本正确。你只需要以不同的方式做两件事:

1)追加时断开循环。

2)删除附加的项目(以后再也不要追加)

您可以采取以下一种方法:

# create a copy of my_list2 because calling pop will mutate the list
temp_list2 = [x for x in my_list2]

new_list = []
for i,x in enumerate(my_list1):
    for j,y in enumerate(temp_list2):
        if x == y[1]:
            new_list.append(temp_list2.pop(j))
            break
print(new_list)
#[[1, 'p1'], [1, 'p2'], [1, 'p4'], [2, 'p1']]

另外,请勿使用in比较值,而是使用==

以下是使用collections.Counter的另一种更有效的方法:

from collections import Counter
list1_counter = Counter(my_list1)

new_list = []
for (value, key) in my_list2:
    if key in list1_counter and list1_counter[key] > 0:
        new_list.append([value, key])
        list1_counter[key] -= 1
print(new_list)
#[[1, 'p1'], [1, 'p2'], [1, 'p4'], [2, 'p1']]

您构建Counter来计算每个"键的出现次数"在my_list1。然后迭代my_list2并检查计数器中是否存在密钥并且计数大于0.如果是,请将该项添加到列表中并减少计数器。

答案 1 :(得分:2)

您可以使用collections.defaultdictmy_list2中的元素按第二项分组,然后在迭代my_list1时使用它们:

>>> from collections import defaultdict, deque
>>> d = defaultdict(deque)
>>> for elem in my_list2:
...     d[elem[1]].append(elem)
>>> [d[elem].popleft() for elem in my_list1]
[[1, 'p1'], [1, 'p2'], [1, 'p4'], [2, 'p1']]

使用deque代替list可以从左侧获得高效的弹出广告。

答案 2 :(得分:1)

试试这个:

new_list = []
tmp_list = my_list2.copy() #only to preserve my_list2
    for i in my_list1:
        index = 0
        for j in tmp_list :
            if i in j[1]:
                new_list.append(tmp_list.pop(index))
                break
            index += 1

答案 3 :(得分:0)

对你而言,它有点直截了当,你已经提前一步阻止了它。

my_list1 = ["p1", "p2", "p4", "p1"]
my_list2 = [[1,"p1"], [1,"p2"], [1,"p3"], [1,"p4"], [2, "p1"], [2, "p2"], [2, "p3"], [2, "p4"]]
choice = 0
final_list = []
list_1_length = len(my_list1)
for each_element in my_list2:
    if each_element[1] == my_list1[choice]:
       final_list.append(each_element)
       choice += 1
       if choice == list_1_length:
          break