【问题标题】:How to loop through two list of lists at once and replace values from one list with the other list?如何一次循环遍历两个列表并将一个列表中的值替换为另一个列表?
【发布时间】:2019-09-01 11:08:43
【问题描述】:

我有两个列表(a 和 b)

它们每行只有 2 个索引。

a(50,000 行)如下所示:

|name|age|
|----|---|
|Dany|021|
|Alex|035|

作为列表的列表,如下所示:

[['Dany', '021'],['Alex','035'], etc...]

b(2000 行)如下所示:

|name|age|
|----|---|
|Paul|   |
|Leon|   |

作为列表的列表,如下所示:

[['Paul', ''],['Leon',''], etc...]

问题:我想同时遍历ab——对于a的每次迭代,如果a[0]b[0]中,我想将对应的a[1]添加到b[1].

通俗地说,我想通过我的a 列表将年龄添加到我的b 列表中,检查姓名是否在a 列表中,如果是,则获取相应的年龄并添加它在对应名称的b 列表中。

我尝试了一个嵌套循环(遍历 b 并且对于每次迭代,遍历 a 以检查在 a[0]a 的任何迭代是否存在于 bb[0] 的迭代中)但是之后就一直迷路吧。

for row in b[1:]: # Excluding the headers
    b_name = row[0]
    b_age = row[1]
    for row in a[1:]:
        if b_name in row[0]:
            b_age = row[1]
        else:
            b_age = ''

问题是我最终只获得了一个 b_age 的值,但应该有 2000 个唯一的 b_age 值?

【问题讨论】:

  • 这些应该是字典,而不是列表。或者你应该使用pandas
  • b_age 设置为一个值不会影响它来自的列表列。
  • 你没有添加任何东西,你只是替换了变量。您的意思是要将它们添加为数字、连接字符串还是列出所有值?
  • @Barmar 在这种情况下我应该如何使用熊猫?
  • IMO,pandas 对于这么小的项目和这么简单的要求来说是大量矫枉过正。

标签: python list loops iteration nested-loops


【解决方案1】:

假设a 中的名称是唯一的,您可以从a 创建一个dict,以避免在替换b 中的空字符串值时一遍又一遍地循环它。例如(在您的示例中添加了几项以说明如果b 中的名称在a 中不存在会发生什么):

a = [['Dany', '021'], ['Alex','035'], ['Joe', '054']]
b = [['Alex',''], ['Dany', ''], ['Jane', '']]

d = {k: v for k, v in a}
b = [[k, d[k]] if k in d else [k, v] for k, v in b]
print(b)
# [['Alex', '035'], ['Dany', '021'], ['Jane', '']]

如果您实际使用的列表只是示例中的简单对列表,那么您可以将上面的 dict 理解替换为 dict(a)

此外,如果不清楚,各种 k, v 引用是为了方便解包嵌套对,但您可以只使用单个变量并使用索引值访问,例如:

{x[0]: x[1] for x in a}

【讨论】:

  • 谢谢@benvc,所以如果这不是一个简单的配对列表,我该怎么做?
  • @luca-martial - 根据嵌套列表的复杂程度,您可能可以在此答案中使用修改后的 dict 理解。如果嵌套列表非常复杂,那么如果您发布它们的外观示例将会很有帮助,以便我们提供更好的帮助。
【解决方案2】:

您可以尝试通过执行 a_dict = dict(a)a 放入字典中,这将导致如下结果:

{'Dany': '021', 'Alex': '035', etc...}

然后你可以做一些简单的事情:

for person in b:
    if person[0] in a_dict:
        person[1] = a_dict[person[0]]

这应该在b 中为您提供类似的内容:

[['Paul', ''], ['Leon', ''], ['Alex', '035'], etc...]

【讨论】:

    【解决方案3】:

    如果你想更新b 中的值,你需要遍历b 的行索引。循环遍历 将不起作用,因为它们不会保持与 b 中源行/列的链接。

    另外,大概你想在b 中指定一个空白年龄作为第二列,只有当a 中的none 名称匹配,而不仅仅是当前 em> 名称不匹配。

    试试这个:

    for b_row_index in range(1, len(b)): # Excluding the headers
        b_name = b[b_row_index][0]
        for a_row in a[1:]:
            if b_name in a_row[0]:
                b[b_row_index][1] = a_row[1]
                break
        else:
            b[b_row_index][1] = ''
    

    【讨论】:

      【解决方案4】:

      您需要对年龄进行字典,以便您可以对b 中的每一行进行一系列快速 O(1) 查找。我会从以下内容开始:

      # Make a dictionary of names to their ages
      age = dict(a)
      
      for row in b:
          try:
              # Set the age of this row to the age of row[0]
              row[1] = age[row[0]]
          except KeyError:
              # End up here if row[0] is not in the "ages" dict
              pass
      

      【讨论】:

      • 在哪一部分?它在这里按预期运行。
      【解决方案5】:

      您可以使用列表:

      a = [['Dany', '021'],['Alex','035'], ['Paul', '060'],['Leon','070']]
      b = [['Paul', ''],['Leon','']]
      
      for i, b_item in enumerate(b):
          for a_item in a:
              if b_item[0]==a_item[0]:
                  b[i] = a_item
                  break
      
      print(b)
      

      输出

      [['Paul', '060'], ['Leon', '070']]
      

      【讨论】:

        【解决方案6】:

        我认为正如许多其他人提到的那样;在这里使用字典会使生活变得更轻松,您可以转换为字典,处理数据并附加年龄,然后在需要时转换回列表。这段代码正是这样做的:

        a = [['Dany', '021'], ['Alex','035'], ['Joe', '054']]
        b = [['Alex',''], ['Dany', ''], ['Jane', '']]
        
        print(a)
        print(b)
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        
        # convert to dict for simplicity
        a_dictionary  = dict(zip([e[0] for e in a], [e[1] for e in a]))
        b_dictionary  = dict(zip([e[0] for e in b], [e[1] for e in b]))
        a_intersect_b = list(set(a_dictionary.keys()) & set(b_dictionary.keys()))
        
        print(a_dictionary)
        print(b_dictionary)
        print(a_intersect_b)
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        
        # copy ages to b
        for k in a_intersect_b:
            b_dictionary[k] = a_dictionary[k]
        
        print(a_dictionary)
        print(b_dictionary)
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        
        # go back to lists
        a = [[name, age] for name, age in zip(a_dictionary.keys(), a_dictionary.values())]
        b = [[name, age] for name, age in zip(b_dictionary.keys(), b_dictionary.values())]
        
        print(a)
        print(b)
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        

        输出:

        [['Dany', '021'], ['Alex', '035'], ['Joe', '054']]
        [['Alex', ''], ['Dany', ''], ['Jane', '']]
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        {'Dany': '021', 'Alex': '035', 'Joe': '054'}
        {'Alex': '', 'Dany': '', 'Jane': ''}
        ['Alex', 'Dany']
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        {'Dany': '021', 'Alex': '035', 'Joe': '054'}
        {'Alex': '035', 'Dany': '021', 'Jane': ''}
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        [['Dany', '021'], ['Alex', '035'], ['Joe', '054']]
        [['Alex', '035'], ['Dany', '021'], ['Jane', '']]
        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-17
          • 2019-07-27
          • 2022-01-06
          相关资源
          最近更新 更多