【问题标题】:Going through 2 lists with array data遍历 2 个包含数组数据的列表
【发布时间】:2018-07-16 10:07:55
【问题描述】:

这个问题让我很头疼,而且我很难找到带有 for 循环的解决方案。

基本上,我的数据如下所示:

short_list = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]
long_list  = [ [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [6, 7, 8, 9, 10], [9, 10, 11, 12, 13] ]

我需要知道 short_list 中每一行的每个数字在 long_list 的每一行中出现了多少次,并且当两个列表索引相同时不需要进行比较,因为它们来自同一个数据集。

示例:我需要知道 long_list 行 [2, 3, 4, 5, 6], [6, 7, 8, 9, 10] 和 [1, 2, 3] 中每个数字的出现次数[9、10、11、12、13]。 然后继续short_list中的下一个数据行,等等。

【问题讨论】:

  • 我看不懂这部分,当两个列表索引相同时,不需要比较,因为它们来自同一个数据集。提供一个显示这种情况的示例.
  • 我的意思是我们已经知道 short_list 中的行 [1, 2, 3] 出现在 [1, 2, 3, 4, 5] 中。我不需要比较这些数字,因为它们是匹配的。这对行的每个索引都有效。我只需要比较两者不相等的索引。
  • 给定示例的正确答案是什么?
  • @ElFred:想要的输出是什么?
  • [ [0, 1, 1], [1, 1, 1], [0, 0, 1], [1, 0, 0] ],从左到右扫描短名单时对。

标签: python arrays list loops


【解决方案1】:

可能的方法

  • 循环遍历short_list 中的每个列表。
  • 展平long_list 中与当前列表不同索引的每个列表,并将其转换为集合。
  • 创建一个collections.Counter() 以将每个元素的计数存储在展平列表中出现的短列表中。

演示:

from collections import Counter
from itertools import chain

short_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
long_list  = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [6, 7, 8, 9, 10], [9, 10, 11, 12, 13]]

for i, short_lst in enumerate(short_list):
    to_check = set(chain.from_iterable(long_list[:i] + long_list[i+1:]))
    print(Counter(x for x in short_lst if x in to_check))

输出:

Counter({2: 1, 3: 1})
Counter({4: 1, 5: 1, 6: 1})
Counter({9: 1})
Counter({10: 1})

【讨论】:

    【解决方案2】:

    这是一个蛮力解决方案。我已经修改了输入数据以使结果更有趣:

    from collections import Counter
    from toolz import concat
    
    short_list = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]
    long_list  = [ [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [6, 7, 8, 9, 10], [2, 3, 11, 12, 13] ]
    
    for idx, i in enumerate(short_list):
        long_list_filtered = (x for x in concat(long_list[:idx] + long_list[idx+1:]) if x in set(i)))
        print(idx, Counter(long_list_filtered))
    
    # 0 Counter({2: 2, 3: 2})
    # 1 Counter({4: 1, 5: 1, 6: 1})
    # 2 Counter()
    # 3 Counter({10: 1})
    

    【讨论】:

      【解决方案3】:
      for L1 in short_list:
        for L2 in long_list:
          if not set(L1).issubset(set(L2)):
            for x in L1:
              print("{} has {} occurrences in {}".format(x, L2.count(x), L2))
      

      【讨论】:

      • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
      • 我实际上选择了这个作为我的首选解决方案,因为它易于理解,而且很短。其他给定的解决方案也是有效的,但是由于简单,这个解决方案赢得了积分。谢谢!
      【解决方案4】:

      这是一种方法。这就是我的想法,所以可能有更好的方法来做到这一点。

      from collections import defaultdict
      
      short_list = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]
      long_list  = [ [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [6, 7, 8, 9, 10], [9, 10, 11, 12, 13] ]
      
      occurrences = defaultdict(int)
      
      for i, sl in enumerate(short_list):
          for j, ll in enumerate(long_list):
              if i != j:
                  for n in sl:
                      occurrences[n] += ll.count(n)
      
      >>> occurrences
      defaultdict(<class 'int'>, {1: 0, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 0, 8: 0, 9: 1, 10: 1, 11: 0, 12: 0})
      

      请注意,enumerate() 用于在迭代时提供索引。比较索引以确保不比较相同相对位置的子列表。

      结果是一个由短列表中的项目作为键的字典,其值是长列表中该项目的总计数,而不是具有相同索引的子列表。

      【讨论】:

      • 这给出了预期的结果!
      【解决方案5】:
      short_list = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]
      long_list  = [ [1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [6, 7, 8, 9, 10], [9, 10, 11, 12, 13] ]
      occ = []
      for si in short_list:
          occi = []
          for i, e in enumerate(si):
              count = 0
              for li in long_list:
                  for j, e1 in enumerate(li):
                      if i == j:
                          continue
                      elif e == e1:
                          count += 1
              occi.append(count)
          occ.append(occi)
      print occ
      

      这应该有效, 快乐编码:)

      【讨论】:

      • 它没有给出预期的结果。结果仅对第一行是正确的。这应该是预期的结果:[ [0, 1, 1], [1, 1, 1], [0, 0, 1], [1, 0, 0] ]
      猜你喜欢
      • 2018-07-03
      • 1970-01-01
      • 2018-10-06
      • 2021-08-07
      • 2021-02-16
      • 2016-08-21
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多