如何一次遍历两个列表列表并将一个列表中的值替换为另一个列表?

How to loop through two list of lists at once and replace values from one list with the other list?

我有两个列表列表(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].

通俗地说,我想将年龄添加到我的 b 列表中,方法是检查我的 a 列表,检查名字是否在 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 值?

假设 a 中的名称是唯一的,您可以从 a 创建一个字典,以避免在替换 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(a)

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

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

您需要对年龄进行口述,以便可以对 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

您可以尝试通过执行 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...]

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

此外,假设您想要在 b 中的第二列指定空白年龄,仅当 none 中的姓名为 a 时] 匹配,不仅仅是 当前 名称不匹配。

试试这个:

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] = ''

使用列表,您可以:

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']]

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

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', '']]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++