对地图对象进行成员资格测试时出现意外结果
Unexpected result with a membership test on a map object
我是 Python 的初学者,正在尝试解决练习 Python 中的 List Overlap 问题。
我已经写了一些代码来解决这个问题,但代码似乎有自己的想法。它有时有效,有时只是 returns 一片空白。我哪里错了?
lista= map(int,input('Enter a list of numbers separated by spaces :').split())
listb= map(int,input('Enter another list of numbers separated by spaces :').split())
listc=[]
for item in lista:
if item in listb:
listc.append(item)
print(listc)
运行之后:
Enter a list of numbers separated by spaces :1 3 5
Enter another list of numbers separated by spaces :3 7 9
[] <-- unexpected result- I was hoping to see a new list with [3] in it.
尝试使用 set 函数而不是循环。
编辑:
更改为重叠而不是唯一列表值。
listc = set(lista) & set(listb)
您遇到的奇怪行为与 map
函数在 Python 3 中的工作方式有关。您可能期望它 returns 是一个列表,就像它在Python2 可以用in
关键字重复查询。然而,在 Python 3 中,map
returns 一个迭代器,它是一个实现 __next__
方法的对象,使映射函数可以延迟应用(但只能是遍历一次)。在迭代器上使用 in
关键字会耗尽它并损害未来 in
调用的准确性:
>>> map(int, ["1", "2", "3"])
<map object at 0x027FF5D0>
>>> it = map(int, ["1", "2", "3"])
>>> 1 in it
True
>>> 1 in it
False
>>> 1 in it
False
如果您的示例类似于 1 2 3
和 1 2 3
,它似乎可以工作,因为迭代器会在 listb
中找到 1
并暂停,找到 2
并暂停,然后找到 3
并暂停,同时耗尽两个迭代器。但是 1 3 5
、3 7 9
失败了,因为 listb
迭代器已用尽搜索 1
和 returns false 对于任何未来的 in
操作。
解决方法是将map
返回的迭代器显式转换为列表:
>>> list(map(int, ["1", "2", "3"]))
[1, 2, 3]
或使用 list comprehension,其中 returns 一个列表并有效地用作映射,将函数应用于输入列表的每个元素:
>>> [int(x) for x in ["1", "2", "3"]]
[1, 2, 3]
进行此更改后,代码应该可以按预期工作。请注意,使 lista
成为一个列表并不是绝对必要的,因为它只被遍历一次(但顾名思义,您希望它成为一个列表):
lista = list(map(int, input('Enter a list of numbers separated by spaces :').split()))
listb = list(map(int, input('Enter another list of numbers separated by spaces :').split()))
# ^^^^
listc = []
for item in lista:
if item in listb:
listc.append(item)
print(listc)
样本运行:
Enter a list of numbers separated by spaces: 1 3 5
Enter a list of numbers separated by spaces: 3 7 9
[3]
有关可迭代对象和迭代器的进一步阅读,请参阅:What exactly are iterator, iterable, and iteration?。
完成此操作后,请注意您的代码没有正确考虑重复项,因此您仍然无法通过您正在尝试的编码挑战。在添加之前,看看您是否可以操纵您的逻辑来检查该值是否已经在 listc
中。使用列表成功完成挑战后,请尝试探索 set
数据结构,正如其他人提到的那样,它提供了一种实现交集的语义和有效方法。
我是 Python 的初学者,正在尝试解决练习 Python 中的 List Overlap 问题。
我已经写了一些代码来解决这个问题,但代码似乎有自己的想法。它有时有效,有时只是 returns 一片空白。我哪里错了?
lista= map(int,input('Enter a list of numbers separated by spaces :').split())
listb= map(int,input('Enter another list of numbers separated by spaces :').split())
listc=[]
for item in lista:
if item in listb:
listc.append(item)
print(listc)
运行之后:
Enter a list of numbers separated by spaces :1 3 5
Enter another list of numbers separated by spaces :3 7 9
[] <-- unexpected result- I was hoping to see a new list with [3] in it.
尝试使用 set 函数而不是循环。
编辑: 更改为重叠而不是唯一列表值。
listc = set(lista) & set(listb)
您遇到的奇怪行为与 map
函数在 Python 3 中的工作方式有关。您可能期望它 returns 是一个列表,就像它在Python2 可以用in
关键字重复查询。然而,在 Python 3 中,map
returns 一个迭代器,它是一个实现 __next__
方法的对象,使映射函数可以延迟应用(但只能是遍历一次)。在迭代器上使用 in
关键字会耗尽它并损害未来 in
调用的准确性:
>>> map(int, ["1", "2", "3"])
<map object at 0x027FF5D0>
>>> it = map(int, ["1", "2", "3"])
>>> 1 in it
True
>>> 1 in it
False
>>> 1 in it
False
如果您的示例类似于 1 2 3
和 1 2 3
,它似乎可以工作,因为迭代器会在 listb
中找到 1
并暂停,找到 2
并暂停,然后找到 3
并暂停,同时耗尽两个迭代器。但是 1 3 5
、3 7 9
失败了,因为 listb
迭代器已用尽搜索 1
和 returns false 对于任何未来的 in
操作。
解决方法是将map
返回的迭代器显式转换为列表:
>>> list(map(int, ["1", "2", "3"]))
[1, 2, 3]
或使用 list comprehension,其中 returns 一个列表并有效地用作映射,将函数应用于输入列表的每个元素:
>>> [int(x) for x in ["1", "2", "3"]]
[1, 2, 3]
进行此更改后,代码应该可以按预期工作。请注意,使 lista
成为一个列表并不是绝对必要的,因为它只被遍历一次(但顾名思义,您希望它成为一个列表):
lista = list(map(int, input('Enter a list of numbers separated by spaces :').split()))
listb = list(map(int, input('Enter another list of numbers separated by spaces :').split()))
# ^^^^
listc = []
for item in lista:
if item in listb:
listc.append(item)
print(listc)
样本运行:
Enter a list of numbers separated by spaces: 1 3 5
Enter a list of numbers separated by spaces: 3 7 9
[3]
有关可迭代对象和迭代器的进一步阅读,请参阅:What exactly are iterator, iterable, and iteration?。
完成此操作后,请注意您的代码没有正确考虑重复项,因此您仍然无法通过您正在尝试的编码挑战。在添加之前,看看您是否可以操纵您的逻辑来检查该值是否已经在 listc
中。使用列表成功完成挑战后,请尝试探索 set
数据结构,正如其他人提到的那样,它提供了一种实现交集的语义和有效方法。