如何一次遍历两个列表列表并将一个列表中的值替换为另一个列表?
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...]
问题:我想同时遍历 a
和 b
- 对于 a
的每次迭代,如果 a[0]
在 b[0]
,我想把对应的a[1]
加到b[1]
.
通俗地说,我想将年龄添加到我的 b
列表中,方法是检查我的 a
列表,检查名字是否在 a
列表中,以及它是否在, 获取相应的年龄并将其添加到相应名称的 b
列表中。
我尝试了一个嵌套循环(遍历 b 并且对于每次迭代,遍历 a
以检查 a[0]
处的 a
的任何迭代是否存在于 b
在 b[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', '']]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
我有两个列表列表(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...]
问题:我想同时遍历 a
和 b
- 对于 a
的每次迭代,如果 a[0]
在 b[0]
,我想把对应的a[1]
加到b[1]
.
通俗地说,我想将年龄添加到我的 b
列表中,方法是检查我的 a
列表,检查名字是否在 a
列表中,以及它是否在, 获取相应的年龄并将其添加到相应名称的 b
列表中。
我尝试了一个嵌套循环(遍历 b 并且对于每次迭代,遍历 a
以检查 a[0]
处的 a
的任何迭代是否存在于 b
在 b[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', '']]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++