【问题标题】:Python 3.x: dict zip two list of the same length has different resultsPython 3.x:dict zip 两个相同长度的列表有不同的结果
【发布时间】:2021-07-22 20:31:37
【问题描述】:

我想创建一个名为pieces的值字典,
给定字典的键必须是片段的名称和它的 Unicode 字符表示的项目。

我决定编写一个列表解析来检索 Unicode 字符和一个包含我需要的所有名称的列表。

pieces = dict(zip(['Queen','King','Tower','Bishop','Knight','Pawn']*2,[chr(int(f'265{i:X}',16)) for i in range(4,16)]))
print(pieces)

>> {'Queen': '♚', 'King': '♛', 'Tower': '♜', 'Bishop': '♝', 'Knight': '♞', 'Pawn': '♟'}

我反转了 zip 函数的参数,我得到了:

pieces = dict(zip([chr(int(f'265{i:X}',16)) for i in range(4,16)],['Queen','King','Tower','Bishop','Knight','Pawn']*2))
print(pieces)

>> {'♔': 'Queen', '♕': 'King', '♖': 'Tower', '♗': 'Bishop', '♘': 'Knight', '♙': 'Pawn', '♚': 'Queen', '♛': 'King', '♜': 'Tower', '♝': 'Bishop', '♞': 'Knight', '♟': 'Pawn'}

我无法理解这些输出。起初我认为可能是第二个参数“引导”了字典的大小,所以我调整了名称列表的大小并混合了参数,我得到了以下结果:

pieces = dict(zip([chr(int(f'265{i:X}',16)) for i in range(4,16)],['Queen','King','Tower','Bishop','Knight','Pawn']))
print(pieces)

>> {'♔': 'Queen', '♕': 'King', '♖': 'Tower', '♗': 'Bishop', '♘': 'Knight', '♙': 'Pawn'}

pieces = dict(zip(['Queen','King','Tower','Bishop','Knight','Pawn'],[chr(int(f'265{i:X}',16)) for i in range(4,16)]))
print(pieces)

>> {'♔': 'Queen', '♕': 'King', '♖': 'Tower', '♗': 'Bishop', '♘': 'Knight', '♙': 'Pawn'}

调整尺寸之前:
第一行代码打印第一个列表的 6 个成员和最后一个列表的最后 6 个成员
第二行代码打印第一个列表的所有成员和第二个列表的所有成员

调整大小后:
这两行都打印了两个列表的前 6 个成员

我的问题是:为什么?

至于我的不相信,只能用以下一句话来表达:

??????

【问题讨论】:

  • zip 仅处理已通过的最短迭代长度。 docs.python.org/3/library/functions.html#zip
  • 你想用来自 ['Queen','King','Tower','Bishop','Knight','Pawn']*2 的键做一个字典 - 但字典键是唯一的,所以它会被更新的对覆盖
  • @h4z3 正如我在 motyzk 回复所说的,我太笨了,我今天应该多喝咖啡!我会将这篇文章保存为我的桌面图像作为警告! :P

标签: python python-3.x dictionary list-comprehension


【解决方案1】:

dict 只能有唯一的键。如果您多次给它相同的键 - 它只会“记住”最后一个值。以前的值将被覆盖。

值得一提的是,zip 将在 Python 3.10 (https://www.python.org/dev/peps/pep-0618/) 上获得一个长度检查标志,这将在提供给 zip 的列表大小不同时引发错误。我想它可以帮助理智地检查这种情况。

【讨论】:

  • 如果zip 有不同大小的迭代,总是有itertools.zip_longest
  • 这不是zip 的两个元素长度不同的问题。 ['Queen','King','Tower','Bishop','Knight','Pawn']*2 与 unicode 字符范围相同的 12 个元素。问题仅在于 6 个关键值被新值覆盖。
  • 您是对的,但正如您在问题中看到的那样 - Fabio 认为他们的代码由于长度不同而无法工作的选项。我列出的提示可以帮助尽早消除该选项。
【解决方案2】:

如果您在 python 中使用重复键创建 dict,则生成的 dict 将具有与赋予它的最后一个值关联的键:

>>> {1:1,1:2,1:3}
{1: 3}

这是一个非常有用的功能!

所代表的列表:

>>> [chr(int(f'265{i:X}',16)) for i in range(4,16)]
['♔', '♕', '♖', '♗', '♘', '♙', '♚', '♛', '♜', '♝', '♞', '♟']

是白色块,然后是黑色块,代表 12 个唯一值。

使用['Queen','King','Tower','Bishop','Knight','Pawn']*2,您不会区分白色和黑色棋子,这仅代表 6 个唯一值。

所以当你这样做时:

>>> list(zip(['Queen','King','Tower','Bishop','Knight','Pawn']*2,[chr(int(f'265{i:X}',16)) for i in range(4,16)]))
[('Queen', '♔'), ('King', '♕'), ('Tower', '♖'), ('Bishop', '♗'), ('Knight', '♘'), ('Pawn', '♙'), 
 ('Queen', '♚'), ('King', '♛'), ('Tower', '♜'), ('Bishop', '♝'), ('Knight', '♞'), ('Pawn', '♟')]

您可以看到,创建的 dict 将更新给定的第一个值(白色块的符号)以表示给定的第二个值(黑色块)。

所以你应该这样做:

>>> piece_type=['Queen','King','Tower','Bishop','Knight','Pawn']
>>> [('White ','Black ')[i>=6]+p for i,p in enumerate(piece_type*2)]
['White Queen', 'White King', 'White Tower', 'White Bishop', 'White Knight', 'White Pawn', 
 'Black Queen', 'Black King', 'Black Tower', 'Black Bishop', 'Black Knight', 'Black Pawn']

(或者只是让列表文字成为 12 个唯一值...)

然后您将获得代表棋盘上唯一 12 个棋子的唯一值。


你也可以是 LAZY,用 Python 库告诉你什么是什么:

import unicodedata as ud
li=[(p,ud.name(p)) 
     for p in (chr(int(f'265{i:X}',16)) for i in range(4,16))]

>>> li
[('♔', 'WHITE CHESS KING'), 
 ('♕', 'WHITE CHESS QUEEN'), 
 ('♖', 'WHITE CHESS ROOK'), 
 ('♗', 'WHITE CHESS BISHOP'), 
 ('♘', 'WHITE CHESS KNIGHT'), 
 ('♙', 'WHITE CHESS PAWN'), 
 ('♚', 'BLACK CHESS KING'), 
 ('♛', 'BLACK CHESS QUEEN'), 
 ('♜', 'BLACK CHESS ROOK'), 
 ('♝', 'BLACK CHESS BISHOP'), 
 ('♞', 'BLACK CHESS KNIGHT'), 
 ('♟', 'BLACK CHESS PAWN')]

这表明['Queen','King','Tower','Bishop','Knight','Pawn'] 的原始列表文字将皇后和国王颠倒了。

然后它会按您期望的两种方式工作:

>>> dict((p,ud.name(p)) for p in (chr(int(f'265{i:X}',16)) for i in range(4,16)))
{'♔': 'WHITE CHESS KING', '♕': 'WHITE CHESS QUEEN', '♖': 'WHITE CHESS ROOK', '♗': 'WHITE CHESS BISHOP', '♘': 'WHITE CHESS KNIGHT', '♙': 'WHITE CHESS PAWN', '♚': 'BLACK CHESS KING', '♛': 'BLACK CHESS QUEEN', '♜': 'BLACK CHESS ROOK', '♝': 'BLACK CHESS BISHOP', '♞': 'BLACK CHESS KNIGHT', '♟': 'BLACK CHESS PAWN'}
>>> dict((ud.name(p),p) for p in (chr(int(f'265{i:X}',16)) for i in range(4,16)))
{'WHITE CHESS KING': '♔', 'WHITE CHESS QUEEN': '♕', 'WHITE CHESS ROOK': '♖', 'WHITE CHESS BISHOP': '♗', 'WHITE CHESS KNIGHT': '♘', 'WHITE CHESS PAWN': '♙', 'BLACK CHESS KING': '♚', 'BLACK CHESS QUEEN': '♛', 'BLACK CHESS ROOK': '♜', 'BLACK CHESS BISHOP': '♝', 'BLACK CHESS KNIGHT': '♞', 'BLACK CHESS PAWN': '♟'}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-04
    • 2017-11-30
    • 2017-12-24
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    相关资源
    最近更新 更多