【问题标题】:Append items to a list according to occurences in another list根据另一个列表中的出现将项目附加到列表中
【发布时间】:2018-09-21 11:57:35
【问题描述】:

所以我有一个清单:

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 新手,所以请温柔一点。我非常感谢任何建议!

【问题讨论】:

  • 你的意思是list2中每一项的第一次出现?
  • 不,我的意思是,前 n 次出现。 n 在某种意义上由列表 my_list1 确定。对于“p1”,应附加前两次出现。
  • 对于第一个p1,我需要第一次出现,对于第二个p1,我需要第二个(......等等......)

标签: python list loops append


【解决方案1】:

对你来说是不是有点直截了当,你已经提前阻止了它。

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

【讨论】:

    【解决方案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 可以有效地从左侧弹出。

    【讨论】:

      【解决方案3】:

      试试这个:

      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
      

      【讨论】:

        【解决方案4】:

        你的代码有一些问题,但逻辑基本正确。你只需要做两件不同的事情:

        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。如果存在,则将该项目添加到列表中并减少计数器。

        【讨论】:

          猜你喜欢
          • 2021-03-17
          • 2020-02-18
          • 1970-01-01
          • 2019-03-13
          • 1970-01-01
          • 2018-02-12
          • 1970-01-01
          • 2015-02-08
          • 1970-01-01
          相关资源
          最近更新 更多