Printing from [Awkward] Python Nested Dictionaries

huangapple go评论100阅读模式
英文:

Printing from [Awkward] Python Nested Dictionaries

问题

I'm just providing the translation of the non-code part of your text:

"所以,我正在学习Python(3.x),一切都很清晰,直到我遇到这个非常奇怪的字典进展,并试图更好地理解它的运作方式。我希望有人能以[简单]的方式解释它为什么会/不会起作用。

我完全意识到可能有更好的方法来做我尝试做的事情 - 所以我愿意看到并学习那些方法!

我需要提取/打印这些示例中的'this_entry'。

dict1 = {'simple':'this_entry';}
dict2 = {'key1':{'key2':'this_entry';}
dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]]}

前两个使用以下方式完全正常:

print (dict1['simple'])
print (dict2['key1']['key2'])

但第三个(显然是设计得更复杂),如果我使用:

print (dict3['key1']['nest_key'][1])

它不起作用并报错...

因此,为了调试,我从基本级别开始查看什么有效/什么无效。

print (dict3['key1']) # 显示 [{'nest_key': ['this is harder', ['hello']]}]
print (dict3['key1']['nest_key'][1]) # 在这里出错显示:
# TypeError: list indices must be integers or slices, not str

为什么会在这里出错?如果我添加一个'指针'来引用键(这是否是正确的词?),它似乎可以工作,我只是想知道为什么在这种情况下它会出错以及为什么需要这个'指针'(除了'没有它就无法正常工作')。

print (dict3['key1'][0]['nest_key'][1]) # 工作得差强人意,但显示条目['hello'],而不是hello

显然还缺少一些内容,因为输出是不正确的。我猜想理解为什么需要第一个[0]也将解释如何正确提取我所需的条目?

提前感谢!"

英文:

So, I'm learning Python (3.x) and it makes a lot of sense until I came across this very awkward progression of dictionaries and trying to get a better understanding of what it is doing. I'm hoping someone could explain in [simple] terms why it does/doesn't work.

I'm fully aware that there may be better ways of doing what I am trying to do - so I'm open to seeing and learning those too!

I need to extract/print 'this_entry' in these examples.

  1. dict1 = {'simple':'this_entry'}
  2. dict2 = {'key1':{'key2':'this_entry'}}
  3. dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}

The first two work absolutely fine using

  1. print (dict1['simple'])
  2. print (dict2['key1']['key2'])

BUT the third one is (obviously designed to be) much more tricky, if I use

  1. print (dict3['key1']['nest_key'][1])

It doesn't work and throws up errors...

So to debug I started with the base level to see what works/what doesn't.

  1. print (dict3['key1']) #shows [{'nest_key': ['this is harder', ['hello']]}]
  2. print (dict3['key1']['nest_key'][1]) #breaks here showing:
  3. #TypeError: list indices must be integers or slices, not str

Why does it break there? If I add in a 'pointer' for the key (is that even the right word?) it kinda works, I just want to know why it breaks if that isn't used and why the 'pointer' is needed in this instance (other than 'it just doesn't work without it').

  1. print (dict3['key1'][0]['nest_key'][1]) #works-ish but shows entry ['hello'], not hello

There's something obviously missing too as the output is incorrect. I'm guessing understaning why I need the first [0] will also explain on how to extract the entry I desire properly?

Thanks in advance!

答案1

得分: 2

Here is the translated code part without the comments:

  1. print(dict3["key1"])
  2. [{ 'nest_key': ['this is harder', ['this_entry'] ] }]
  3. print(dict3["key1"][0])
  4. { 'nest_key': ['this is harder', ['this_entry'] ] }
  5. print(dict3["key1"][0]["nest_key"])
  6. ['this is harder', ['this_entry']]
  7. print(dict3["key1"][0]["nest_key"][1])
  8. ['this_entry']
  9. print(dict3["key1"][0]["nest_key"][1][0])
  10. this_entry
英文:

With your given dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}, consider running the following statements, and the output they give:

  1. >>> print(dict3["key1"]) # access the value of 'key1', the value is a list
  2. [{'nest_key': ['this is harder', ['this_entry']]}]
  3. >>> print(dict3["key1"][0]) # access the 1st elemtn of the list which is a dict
  4. {'nest_key': ['this is harder', ['this_entry']]}
  5. >>> print(dict3["key1"][0]["nest_key"]) # access the value of 'nest_key, the value is a list
  6. ['this is harder', ['this_entry']]
  7. >>> print(dict3["key1"][0]["nest_key"][1]) # get 2nd element of the list, which is another list
  8. ['this_entry']
  9. >>> print(dict3["key1"][0]["nest_key"][1][0]) # finaly get the single item in the list, value is a string
  10. this_entry

答案2

得分: 0

  • dict3['key1'] - 返回一个列表
    • 例如 [{'nest_key': ['this is harder']}]
  • dict3['key1'][0] - 返回列表中的第一个项目
    • 例如 {'nest_key': ['this is harder']}
  • dict3['key1'][0]['nest_key'] - 返回内部字典中的 nest_key 值
    • 例如 ['this is harder']
  • dict3['key1'][0]['nest_key'][0] - 返回内部字典中的第一个项目
    • 例如 'this is harder'
  • dict3['key1'][0]['nest_key'][1] - 返回内部字典中的第二个项目
    • 例如 ['this_entry']
  • dict3['key1'][0]['nest_key'][1][0] - 返回内部字典中第二个项目中的第一个字符串
    • 例如 'this_entry'
  • dict3['key1'][0]['nest_key'][1][0][0] - 返回内部字典中第二个项目中第一个字符串的第一个字符
    • 例如 't'

希望这有所帮助。

英文:

TL;DR

  • dict3['key1'] -> returns a list
    • i.e. [{'nest_key': ['this is harder']}]
  • dict3['key1'][0] -> returns first item in the list
    • i.e. {'nest_key': ['this is harder']}
  • dict3['key1'][0]['nest_key'] -> returns the nest_key value in the inner dict
    • i.e. ['this is harder']
  • dict3['key1'][0]['nest_key'][0] -> returns the first item in the inner dict
    • i.e. 'this is harder'
  • dict3['key1'][0]['nest_key'][1] -> returns the 2nd item in the inner dict
    • i.e. ['this_entry']
  • dict3['key1'][0]['nest_key'][1][0] -> returns the 1st string in the 2nd item in the inner dict
    • i.e. 'this_entry'
  • dict3['key1'][0]['nest_key'][1][0][0] -> returns the 1st character of the 1st string in the 2nd item in the inner dict
    • i.e. 't'

In Long

Firstly, collections.defaultdict is a good friend. https://docs.python.org/3/library/collections.html#collections.defaultdict

An example usage:

  1. from collections import defaultdict
  2. x = defaultdict(list)
  3. x['key1'].append('abc')
  4. print(x)

[out]:

  1. defaultdict(<class 'list'>, {'key1': ['abc']})

Next if we kind of initialize the "types" of your dict3 object, it will look something like this:

In human words, dictionary of list of dictionary of list of strings or list of strings, i.e. "messy"/"awkward", see also

In Python types:

  1. from collections import defaultdict
  2. x = defaultdict(lambda: [defaultdict] )
  3. x['key1'].append({'abc': 'foo bar'})
  4. print(x)

[out]:

  1. defaultdict(<function <lambda> at 0x7f75cebca0d0>,
  2. {'key1': [<class 'collections.defaultdict'>, {'abc': 'foo bar'}]})

If we look at first how you can/should initialize dict3 type, you would do something like:

  1. from collections import defaultdict
  2. x = defaultdict(lambda: list(defaultdict(lambda: list)) )
  3. x['key1'].append({'nest_key': ['this is harder']})
  4. print(x)

[out]:

  1. defaultdict(<function <lambda> at 0x7f75cee11940>,
  2. {'key1': [defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f75cf38c4c0>, {}),
  3. {'nest_key': ['this is harder']}]})

And then to access the 'this is harder' string you would do:

  • x['key1'] -> returns a list
    • i.e. [{'nest_key': ['this is harder']}]
  • x['key1'][0] -> returns first item in the list
    • i.e. {'nest_key': ['this is harder']}
  • x['key1'][0]['nest_key'] -> returns the nest_key value in the inner dict
    • i.e. ['this is harder']
  • x['key1'][0]['nest_key'][0] -> returns the first item in the inner dict
    • i.e. 'this is harder'

But what happens if I want dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}, where the penultimate inner most list contains a list or string?

To initialize the values, you would have done something like

  1. from collections import defaultdict
  2. x = defaultdict(lambda: list(defaultdict(lambda: list)) )
  3. x['key1'].append({'nest_key': ['this is harder']})
  4. x['key1'][0]['nest_key'].append('this is inserting a string')
  5. x['key1'][0]['nest_key'].append(['this is inserting a list'])
  6. print(type(x['key1'][0]['nest_key'][0])) # "this is harder" -> str
  7. print(type(x['key1'][0]['nest_key'][1])) # "this is inserting a string" -> str
  8. print(type(x['key1'][0]['nest_key'][2])) # ['this is inserting a list'] -> list

[out]:

  1. <class 'str'>
  2. <class 'str'>
  3. <class 'list'>

To summarize the initialization:

Human words Initialization Usage Outputs
dictionary of list x = defaultdict(list) x['key1'].append('abc') {'key1': ['abc']}
dictionary of list of dict x = defaultdict(lambda: list(defaultdict)) x['key1'].append({'key2':'abc'})` {'key1': [{'key2':'abc'}]}
dictionary of list of dict of list x = defaultdict(lambda: list(defaultdict(lambda: list)) ) x['key1'].append({'key2': ['foo bar']}) defaultdict(<function <lambda> at 0x7f75cebbcc10>, {'key1': [defaultdict(<function <lambda>.<locals>.<lambda> at 0x7f75cebbc940>, {}), {'key2': ['foo bar']}]})

Q: Why do I bother with how the object is initialize if I just to want access an item inside?

A: If you don't know how the object is initialize, you most probably can't modify / remove / add items. And also knowing how it's initialized also helps you understand how to access the items inside.

Food for thought

If access/parsing to the item you want is kinda complicated, is there an easier way to store your data? I.e. is there a better data structure?

答案3

得分: 0

dict3['key1'] = [{'nest_key': ['this is harder', ['hello']]}]

以字典包含在数组中的形式回答

dict3['key1'][0] = {'nest_key': ['this is harder', ['hello']]}

以只有字典形式回答(nest_key: 2D数组)

dict3['key1'][0]['nest_key'] = ['this is harder', ['hello']]

以2D数组形式回答

dict3['key1'][0]['nest_key'][0] = 'this is harder', ['hello']

dict3['key1'][0]['nest_key'][0][1] = 'hello'

英文:

dict3['key1'] = [{'nest_key': ['this is harder', ['hello']]}]
#answers with a dictionary in a array

dict3['key1'][0] = {'nest_key': ['this is harder', ['hello']]}
#answers with just a dictionary (nest_key : 2D array)

dict3['key1'][0]['nest_key'] = ['this is harder', ['hello']]
#answers with 2D array

dict3['key1'][0]['nest_key'][0] = 'this is harder', ['hello']

dict3['key1'][0]['nest_key'][0][1] = 'hello'

答案4

得分: 0

Thanks to all for the answers, I have a much better understanding now and understand the terminology better too. I think this sums up what I was trying to learn:

  1. dict3 = {'key1':[{'nest_key':['this is harder',['this_entry']]}]}
  2. # to extract/grab/print 'this_entry'
  3. print (dict3['key1'][0]['nest_key'][1][0])

The first part ['key1'][0] is required as it's a list with just a single element - and this is what we/I want to access. Next, to look at ['nest_key'] index 1, thus the [1], and here it has again a single element thus requiring the final index of [0].

All makes much more sense and understood where I was going wrong.

英文:

Thanks to all for the answers, I have a much better understanding now and understand the terminology better too. I think this sums up what I was trying to learn:

  1. dict3 = {&#39;key1&#39;:[{&#39;nest_key&#39;:[&#39;this is harder&#39;,[&#39;this_entry&#39;]]}]}
  2. # to extract/grab/print &#39;this_entry&#39;
  3. print (dict3[&#39;key1&#39;][0][&#39;nest_key&#39;][1][0])

The first part ['key1'][0] is required as it's a list with just a single element - and this is what we/I want to access. Next, to look at ['nest_key'] index 1, thus the [1], and here it has again a single element thus requiring the final index of [0].

All makes much more sense and understood where I was going wrong.

huangapple
  • 本文由 发表于 2023年3月20日 23:32:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792269.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定