【问题标题】:What is an elegant way to convert a python dictionary into a comma separated keys string and a comma separated values string?将python字典转换为逗号分隔键字符串和逗号分隔值字符串的优雅方法是什么?
【发布时间】:2015-07-13 12:25:52
【问题描述】:

我有一本字典如下:-

dict={'a':'1','b':'2', 'c':'3'}

要将其转换为逗号分隔的键字符串key_string 和逗号分隔的值字符串val_string,我执行以下操作:-

key_list=[]
val_list=[]

 for key,value in dict.iteritems():
     key_list.append(key)
     val_list.append(value)

 key_string = ','.join(key_list)
 val_string = ','.join(val_list)

结果是

 key_string = "a,b,c"
 val_string = "1,2,3" 

有没有更高效/优雅的方式来做到这一点?

【问题讨论】:

  • 你想要“高效”还是“优雅”?两者经常有交叉的目的。你的意思是“高效”,如“最少时间”或“最少临时空间”或其他一些衡量标准?
  • 如果我告诉你val_string = ','.join(dict.values()),我相信你可以解决另一个......
  • 这样的? ','.join(map(lambda x:str(x), [1,2]))
  • 您是否希望键/值按任何特定顺序排列?
  • @AshishAcharya:这并不能分离出键和值。而lambda x: str(x) 只是想写str 更慢、更不优雅。反正也没必要,因为他所有的键和值都已经是字符串了。

标签: python string function dictionary


【解决方案1】:

显而易见的解决方案是只使用iterkeysitervalues 而不是iteritems

key_string = ','.join(d.iterkeys())
val_string = ','.join(d.itervalues())

如果您担心键和值以不同的顺序显示,而 Python 允许 dicts 以他们想要的任何顺序进行迭代,它确实记录了 here 如果您一遍又一遍地迭代它们而不做任何其他事情你会得到相同的订单:

如果调用 items()keys()values()iteritems()iterkeys()itervalues(),而没有对字典进行干预修改,则列表将直接对应。

(2.7 文档从未更新过这样说,但 viewitemsviewkeysviewvalues 也是如此。)


至少在 CPython 中,使用 keysvalues 而不是 iterkeysitervalues 可能会更有效(因为,当给定迭代器时,str.join 的 CPython 实现只会使清单),但我怀疑这很重要。正如 Padraic Cunningham 在 cmets 中指出的那样,对于键(但不是值),您可以使用 list(d) 而不是 d.keys() 更快地获得相同的列表(尽管可能不会——它避免了 @987654342 @ 调用,但以 LOAD_NAME 为代价,除非您首先将 list 复制到本地,以便它可以是 LOAD_FASTed)。


最后,如果你想用iteritems 来做这件事(假设你正在使用一个损坏的、不完全兼容的 Python 解释器,它每次都会随机化迭代顺序),你可以使用zip

keys, values = zip(*d.iteritems())

这会将一对序列变成一对序列。

【讨论】:

  • 您可以只在 d 上调用 "".join() 而无需调用 .iterkeys 尽管正如您已经说过的 list(d) 之类的东西会更有效,在 python 3 不同的脚本运行中也是如此可以更改键和值的顺序,这与 python 2 的行为不同。
  • @PadraicCunningham:是的,我想','.join(list(d)) 可能是 CPython 2.7 中最高效的。如果有人真的关心,我会测试所有的可能性,但我怀疑有人会这样做。无论如何,对于与itervalues() 的并行性,我认为iterkeys() 在这里更具可读性。
  • @PadraicCunningham:至于运行之间的顺序,实际上,Python 绝对不能保证每次运行都会得到相同的顺序。 2.7 和 3.4 的命令措辞几乎相同。确实,CPython 3.4 默认使用哈希随机化字符串,而 2.7(和 3.3)没有,但是 Jython 2.5 已经在每次运行中为您提供了不同的顺序,同时,有人谈论让 dict 保留插入在 CPython 3.5 中默认排序(甚至可能需要它用于其他实现),所以这并不是 Python 2 与 Python 3 的真正区别。
  • @abarnet ,我一直认为在 cpython 2.7 上,至少对于字符串和整数,您在不同的运行中总是会得到相同的顺序。
  • @PadraicCunningham:是的,但这是特定于实现的东西,而不是 2.x-vs.-3.x 的差异。 CPython 1.0-3.3 的行为方式相同,CPython 3.4 的行为方式不同,CPython 3.5 的行为方式可能不同,Jython 2.2-2.5 的行为方式不同,我不知道 IronPython 或 Skulpt 等。你不应该假设“ Python 2”表示“运行顺序相同”,或者“Python 3”表示“随机顺序”。
【解决方案2】:

使用str.join(iterable)(提示:不要将你的字典命名为dict):

d = {'a':'1', 'b':'2', 'c':'3'}
print(",".join(d.keys()))
print(",".join(d.values()))

输出:

c,a,b
3,1,2

请注意,字典没有顺序。所以输出也没有任何可以依赖的顺序。

【讨论】:

    【解决方案3】:

    你可以这样做:

    key_string = ','.join(dict.keys()) 
    val_string = ','.join(dict.values())
    

    【讨论】:

      【解决方案4】:

      使用相同的函数str.join(iterable),如果字典值不都是字符串则使用list-comprehension shorthand

      d = {'a': '1', 'b': 2, 'c': {'d': 3}, 'e': [4,5,6]}
      print(",".join(d.keys()))
      print(",".join([str(e) for e in d.values()]))
      

      输出:

      a,b,c,e
      1,2,{'d': 3},[4, 5, 6]
      

      如果您想要自定义格式,那么这将是一个优雅的抽象。将 str(e) 替换为您的自定义格式化程序 myFormatter(e)

      【讨论】:

      • 我发布了这个解决方案,因为我的字典出现异常:TypeError: sequence item 1: expected str instance, int found
      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-18
      • 2018-02-22
      • 1970-01-01
      相关资源
      最近更新 更多