【问题标题】:Convert [key1,val1,key2,val2] to a dict?将 [key1,val1,key2,val2] 转换为字典?
【发布时间】:2011-06-02 08:16:34
【问题描述】:

假设我在 Python 中有一个 a 列表,其条目可以方便地映射到字典。每个偶数元素代表字典的键,后面的奇数元素是值

例如,

a = ['hello','world','1','2']

我想将其转换为字典b,其中

b['hello'] = 'world'
b['1'] = '2'

在语法上最简洁的方法是什么?

【问题讨论】:

标签: python list dictionary


【解决方案1】:
b = dict(zip(a[::2], a[1::2]))

如果a 很大,您可能会想要执行以下操作,这不会像上面那样创建任何临时列表。

from itertools import izip
i = iter(a)
b = dict(izip(i, i))

在 Python 3 中,您也可以使用 dict 理解,但具有讽刺意味的是,我认为最简单的方法是使用 range()len(),这通常是代码异味。

b = {a[i]: a[i+1] for i in range(0, len(a), 2)}

所以iter()/izip() 方法可能仍然是 Python 3 中最 Pythonic 的方法,尽管正如 EOL 在评论中指出的那样,zip() 在 Python 3 中已经是惰性的,因此您不需要 izip()

i = iter(a)
b = dict(zip(i, i))

在 Python 3.8 及更高版本中,您可以使用“walrus”运算符 (:=) 在一行上编写:

b = dict(zip(i := iter(a), i))

否则,您需要使用分号将其放在一行中。

【讨论】:

  • ... 或简单的 zip(i, i),在 Python 3 中,因为 zip() 现在返回一个迭代器。
  • 请注意,Python 2.7.3 也有字典理解
  • 或简单如下({'abc': a, 'def' : b} for a, b in zip(list1, list2))
【解决方案2】:

简单回答

另一种选择(Alex Martelli - source 提供):

dict(x[i:i+2] for i in range(0, len(x), 2))

相关说明

如果你有这个:

a = ['bi','double','duo','two']

并且你想要这个(列表的每个元素都键入一个给定的值(在本例中为 2)):

{'bi':2,'double':2,'duo':2,'two':2}

你可以使用:

>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}

【讨论】:

  • 这仅适用于 Python 3 吗?
  • 使用fromkeys>>> dict.fromkeys(a, 2) {'bi': 2, 'double': 2, 'duo': 2, 'two': 2}
  • 这不是问题所要求的。
  • 出于某种原因dict.fromkeys() 正在复制每个键的值(就像我给的项目都是“链接”或指向内存中的同一个位置)尝试:a = dict.fromkeys(['op1', 'op2'], {}) 然后@ 987654331@ 你会看到a["op2"] 也被填充了
【解决方案3】:

你可以很容易地使用字典推导:

a = ['hello','world','1','2']

my_dict = {item : a[index+1] for index, item in enumerate(a) if index % 2 == 0}

这相当于下面的for循环:

my_dict = {}
for index, item in enumerate(a):
    if index % 2 == 0:
        my_dict[item] = a[index+1]

【讨论】:

    【解决方案4】:

    我觉得很酷的一点是,如果您的列表只有 2 项长:

    ls = ['a', 'b']
    dict([ls])
    >>> {'a':'b'}
    

    请记住,dict 接受任何包含可迭代对象的可迭代对象,其中可迭代对象中的每个项目本身必须是具有两个对象的可迭代对象。

    【讨论】:

    • 快速简单的一个,如果列表包含两个以上的项目,则只需添加,然后使用 dict(ls) 而不是 dict([ls])。例如如果 ls=['a', 'b', 'c', 'd'] 那么 dict(ls)
    • 美观时尚。 'iterable 中的每个项目本身必须是一个包含两个对象的 iterable。' 是这里的关键事实。
    • 这确实值得更多的支持,上面一半的答案是相同的,只是说使用 zip...
    【解决方案5】:

    可能不是最pythonic,但是

    >>> b = {}
    >>> for i in range(0, len(a), 2):
            b[a[i]] = a[i+1]
    

    【讨论】:

    • 阅读enumerate
    • enumerate 不允许您指定步长,但您可以使用 for i, key in enumerate(a[::2]):。仍然是 unpythonic,因为 dict 构造函数可以为您完成大部分工作
    • @SilentGhost,gnibbler:非常感谢你拓宽了我的视野!我一定会在未来尽可能地融入它!
    • @gnibbler:您能否详细解释一下for i, key in enumerate(a[::2]): 方法的工作原理?结果对值将是0 hello1 1,我不清楚如何使用它们来生成{'hello':'world', '1':'2'}
    • @martineau,你是对的。我想我一定是说enumerate(a)[::2]
    【解决方案6】:

    您无需创建额外的数组即可快速完成此操作,因此即使对于非常大的数组也可以使用:

    dict(izip(*([iter(a)]*2)))
    

    如果你有一个生成器a,那就更好了:

    dict(izip(*([a]*2)))
    

    这是纲要:

    iter(h)    #create an iterator from the array, no copies here
    []*2       #creates an array with two copies of the same iterator, the trick
    izip(*())  #consumes the two iterators creating a tuple
    dict()     #puts the tuples into key,value of the dictionary
    

    【讨论】:

    • 这将创建一个具有相等键值对的字典 ({'hello':'hello','world':'world','1':'1','2':'2'})
    • 不,一切正常。请仔细阅读。它说:“如果你有一个生成器......”如果你没有一个生成器,只需使用第一行。如果你有一个生成器而不是一个列表,第二个是一种替代方法,它会很有用,就像大多数时候一样。
    【解决方案7】:

    你也可以这样(这里是字符串到列表的转换,然后是字典的转换)

        string_list = """
        Hello World
        Goodbye Night
        Great Day
        Final Sunset
        """.split()
    
        string_list = dict(zip(string_list[::2],string_list[1::2]))
    
        print string_list
    

    【讨论】:

      【解决方案8】:

      我也非常有兴趣为这种转换提供一个单行,因为这样的列表是 Perl 中散列的默认初始化程序。

      这个帖子给出了非常全面的答案-

      我的一个我是 Python 新手),使用 Python 2.7 Generator Expressions,将是:

      dict((a[i], a[i + 1]) for i in range(0, len(a) - 1, 2))

      【讨论】:

        【解决方案9】:

        我不确定这是否是 pythonic,但似乎可以工作

        def alternate_list(a):
           return a[::2], a[1::2]
        
        key_list,value_list = alternate_list(a)
        b = dict(zip(key_list,value_list))
        

        【讨论】:

          【解决方案10】:

          试试下面的代码:

            >>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
            >>> d2
                {'three': 3, 'two': 2, 'one': 1}
          

          【讨论】:

            【解决方案11】:

            您也可以尝试这种方法将键和值保存在不同的列表中,然后使用 dict 方法

            data=['test1', '1', 'test2', '2', 'test3', '3', 'test4', '4']
            
            keys=[]
            values=[]
            for i,j in enumerate(data):
                if i%2==0:
                    keys.append(j)
                else:
                    values.append(j)
            
            print(dict(zip(keys,values)))
            

            输出:

            {'test3': '3', 'test1': '1', 'test2': '2', 'test4': '4'}
            

            【讨论】:

              【解决方案12】:
              {x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}
              
              result : {'hello': 'world', '1': '2'}
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-11-19
                • 2023-04-05
                • 1970-01-01
                • 2017-05-04
                • 2015-12-04
                • 1970-01-01
                • 2021-06-18
                • 2011-11-30
                相关资源
                最近更新 更多