【问题标题】:Pulling elements from dict/OrdredDict in arbitrary order以任意顺序从 dict/OrdredDict 中提取元素
【发布时间】:2014-03-13 18:29:04
【问题描述】:

我有一个 OrderedDict,其中的元素(如碳和铁)按元素周期表的顺序排列。我需要以任意顺序提取一些元素并保留任意顺序,以便它们匹配以后使用 numpy 进行的数学运算。

如果我对 OrderedDict 进行列表理解,我会得到 OrderedDict 顺序中的元素。但是如果我将它转换为字典,那么我会以正确的任意顺序获得元素(我希望不会意外!)

当然,如果我旋转自己的循环,那么我可以按任意顺序拉取元素。

任何人都可以阐明这两个(显然相同的)列表推导之间显然不相同的区别是什么。

代码:

from collections import OrderedDict

MAXELEMENT = 8

ElementalSymbols = ['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O']        
ElementalWeights = [1.00794, 4.002602, 6.941, 9.012182, 10.811, 12.0107, 14.0067, 15.9994];

ElementDict= OrderedDict(zip(ElementalSymbols, zip(range(0, MAXELEMENT), ElementalWeights)))

NewOrder = ['Be', 'C', 'H']

# This makes NewList have the same order as ElementDict, not NewOrder.
NewList = [(k, el[1]) for k, el in ElementDict.items() if k in NewOrder]

print NewList
# Results in:
#[('H', 1.00794), ('Be', 9.012182), ('C', 12.0107)]

# We do EXACTLY the same thing but change the OrderedDict to a dict.
ElementDict= dict(ElementDict)
# Same list comprehension, but not it is in NewOrder order instead of ElementDict order.
NewList = [(k, el[1]) for k, el in ElementDict.items() if k in NewOrder]

print NewList
# Results in:
#[('Be', 9.012182), ('C', 12.0107), ('H', 1.00794)]

# And, of course, the kludgy way to do it and be sure the elements are in the right order.
for i, el in enumerate(NewOrder):
    NewList[i] = (NewOrder[i], ElementDict[NewOrder[i]][1])

print NewList
# Results in:
#[('Be', 9.012182), ('C', 12.0107), ('H', 1.00794)]

【问题讨论】:

  • dictordered 是稳定的,但不可预测 - 如果您得到预期的订单,那实际上是个意外。
  • 我认为可能是这种情况,在这种情况下我应该使用循环——除非有人有更好的方法来理解它。

标签: python dictionary list-comprehension ordereddictionary


【解决方案1】:

如果你想要一个特定的顺序,你可以把它作为字典的输入,如果你把它作为一个生成器表达式间接地发送到OrderedDict:

MAXELEMENT = 8
ElementalSymbols = ['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O']        
ElementalWeights = [1.00794, 4.002602, 6.941, 9.012182, 10.811, 12.0107, 14.0067, 15.9994];

ElementDict= OrderedDict(zip(ElementalSymbols, zip(range(0, MAXELEMENT), ElementalWeights)))

NewOrder = ['Be', 'C', 'H']

BlueMonday = OrderedDict((x, ElementDict[x]) for x in NewOrder)

print BlueMonday
OrderedDict([('Be', (3, 9.012182)), ('C', (5, 12.0107)), ('H', (0, 1.00794))])
print BlueMonday.items()
[('Be', (3, 9.012182)), ('C', (5, 12.0107)), ('H', (0, 1.00794))]

这与您已经在做的类似,但可能不那么笨拙?

【讨论】:

  • 顺便说一句,也许你已经抓住了这个 - 但你想要,你甚至不需要创建字典 - 你可以直接从生成器中创建一个列表,如果你打算这样使用它。
【解决方案2】:

如果你想要随机顺序,你应该使用random模块,特别是random.sample

【讨论】:

  • 我想要任意顺序,而不是随机顺序。该顺序基于在第二种情况下由不同材料制成的一系列薄膜。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多