我有一个大约17,000键的字典.我想一次选择一个键 - 哪个键无关紧要,我不需要以任何特定顺序发生(随机就好了).但是,在我选择一个键之后,我会在选择另一个键之前更改字典,可能是通过添加或删除键.因此,我没有可以迭代的密钥集.
由于我不需要以任何特定顺序访问它们,我可以每次将dict键转换为列表,然后弹出第一个元素.但是,由于有17,000个键,因此在每次迭代时制作一个列表大约需要0.0005-7秒,这将花费我太多的时间来满足我的需要.有没有我可以采取的快捷方式,以便每次我想选择一个密钥时,我不必用dict键编译一个庞大的列表?
我有一个包含JSON对象的文件.它已按以下方式加载:
with open('data.json', 'r') as input_file:
input_data = input_file.read()
Run Code Online (Sandbox Code Playgroud)
此时input_data只包含一个字符串,现在我继续将其解析为JSON:
data_content = json.loads(input_data.decode('utf-8'))
Run Code Online (Sandbox Code Playgroud)
data_content具有字符串的JSON表示,这是我需要的,但由于某些原因,在json.loads之后我不清楚它正在改变键的原始顺序,所以例如,如果我的文件包含如下内容:
{ "z_id": 312312,
"fname": "test",
"program": "none",
"org": null
}
Run Code Online (Sandbox Code Playgroud)
在json.loads之后,订单被改变为让我们说:
{ "fname": "test",
"program": None,
"z_id": 312312,
"org": "none"
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?有没有办法保存订单?我正在使用Python 2.7.
根据PEP 468:
从版本3.6开始,Python将保留传递给函数的关键字参数的顺序.为了实现这一点,收集的kwargs现在将是有序映射.请注意,这并不一定意味着
OrderedDict.
在这种情况下,为什么这个有序映射无法与Python的规范有序映射类型进行相等比较,collections.OrderedDict:
>>> from collections import OrderedDict
>>> data = OrderedDict(zip('xy', 'xy'))
>>> def foo(**kwargs):
... return kwargs == data
...
>>> foo(x='x', y='y') # expected result: True
True
>>> foo(y='y', x='x') # expected result: False
True
Run Code Online (Sandbox Code Playgroud)
虽然现在保留了迭代顺序,但kwargs似乎表现得像比较的普通字典.从3.5开始,Python有一个C实现的有序字典,因此它可以直接使用(或者,如果性能仍然是一个问题,使用3.6紧凑字典的瘦子类更快的实现).
为什么函数接收的有序映射不会在相等比较中遵循排序?
现在,从Python 3.7(以及CPython 3.6)开始,保证Python字典的插入顺序是什么,对字典进行排序的最佳/最快方法是什么 - 按值和按键排序?
最明显的方法是:
by_key = {k: dct[k] for k in sorted(dct.keys())}
by_value = {k: dct[k] for k in sorted(dct.keys(), key=dct.__getitem__)}
Run Code Online (Sandbox Code Playgroud)
有没有其他更快的方法来做到这一点?
请注意,这个问题并不重复,因为之前有关如何对字典进行排序的问题已经过时(答案基本上是,您不能;使用collections.OrderedDict替代).
在Python中,当你想使用列表作为某些字典的键时,你可以把它们变成元组,这些元组是不可变的,因此是可以删除的.
>>> a = {}
>>> a[tuple(list_1)] = some_value
>>> a[tuple(list_2)] = some_other_value
Run Code Online (Sandbox Code Playgroud)
当您想要将set对象用作某些字典的键时,也会发生同样的情况- 您可以构建一个冷冻集,这也是不可变的,因此是可清除的.
>>> a = {}
>>> a[frozenset(set_1)] = some_value
>>> a[frozenset(set_2)] = some_other_value
Run Code Online (Sandbox Code Playgroud)
但似乎对于字典没有等价物.
我想到的第一个想法(最终发现它很糟糕)是str(some_dict)用作关键.但是,字典总是使用不同的散列函数,因此相同字典的字符串可能不同.
是否有任何解决方法称为良好实践,或者是否有人有其他想法如何使用类字典对象作为其他词典的键?
有人问这里时,把原因1和True在set仅1被保留.
这当然是因为1==True.但在哪些情况下1保留并保留哪些情况True?
让我们来看看:
传递一个list来构建set而不是使用set符号:
>>> set([True,1])
{True}
>>> set([1,True])
{1}
Run Code Online (Sandbox Code Playgroud)
似乎是逻辑的:set迭代内部列表,并且不添加第二个元素,因为它等于第一个元素(注意set([True,1]) 不能产生1,因为set无法知道列表中的内容.它甚至可能不是list一个可迭代的)
现在使用set符号:
>>> {True,1}
{1}
>>> {1,True}
{True}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,似乎是以相反的顺序处理项目列表(在Python 2.7和Python 3.4上测试).
但这有保证吗?或者只是一个实现细节?
我知道dicts和sets不是有序的,所以相同的set或dicts可能会以不同的方式打印(所有测试都使用Python 3.6.1):
>>> for obj in {0, 8}, {8, 0}, {0:0, 8:8}, {8:8, 0:0}:
print(obj)
{0, 8}
{8, 0}
{0: 0, 8: 8}
{8: 8, 0: 0}
Run Code Online (Sandbox Code Playgroud)
我只是意识到pprint("漂亮的印刷品")对dicts进行了排序,但没有设置:
>>> for obj in {0, 8}, {8, 0}, {0:0, 8:8}, {8:8, 0:0}:
pprint.pprint(obj)
{0, 8}
{8, 0}
{0: 0, 8: 8}
{0: 0, 8: 8}
Run Code Online (Sandbox Code Playgroud)
它的文档还说"字典在计算显示之前按键排序".但为什么不排序?对我来说似乎不太好看.有没有办法让它排序?也在嵌套结构中,因为这是一个主要目的pprint.
在Javascript中,我可以使用解构从一个衬里的javascript对象中提取所需的属性。例如:
currentUser = {
"id": 24,
"name": "John Doe",
"website": "http://mywebsite.com",
"description": "I am an actor",
"email": "example@example.com",
"gender": "M",
"phone_number": "+12345678",
"username": "johndoe",
"birth_date": "1991-02-23",
"followers": 46263,
"following": 345,
"like": 204,
"comments": 9
}
let { id, username } = this.currentUser;
console.log(id) // 24
console.log(username) //johndoe
Run Code Online (Sandbox Code Playgroud)
在Python中,对于Python字典和Python对象,我们是否有类似的东西?适用于python对象的Python方法示例:
class User:
def __init__(self, id, name, website, description, email, gender, phone_number, username):
self.id = id
self.name = name
self.website = website
self.description = description
self.email = email
self.gender = gender …Run Code Online (Sandbox Code Playgroud) 经过一番深入的阅读,所有文档都引出了关于字典的两件事:
如果是这样的话,为什么这个字典只消耗368字节的RAM,而一个空的字典要占用240字节,难道不应该将它调整为4倍大小,例如:960字节吗?
>>> getsizeof(dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7))
368
>>> getsizeof(dict(a=1,b=2,c=3))
240
Run Code Online (Sandbox Code Playgroud)
我是误会还是误解了这里的核心内容?关于python 3.7的此信息是否有所更改?
python ×10
dictionary ×5
set ×2
function ×1
immutability ×1
javascript ×1
json ×1
kwargs ×1
performance ×1
pprint ×1
python-2.7 ×1
python-3.6 ×1
python-3.7 ×1
python-3.x ×1