user9371654
user9371654

Reputation: 2408

How to access a value of a dictionary inside dictionary in python

I want to access the value of "commonName" in this script: The output generates error:

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    print(x["subject"]["commonName"])
TypeError: tuple indices must be integers or slices, not str

I could access x["subject"] but this is not what I want exactly. I want the commonName value and could not access it.

x = {'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('organizationName', 'Google Inc'),), (('commonName', '*.google.com'),)), 'issuer': ((('countryName', 'US'),), (('organizationName', 'Google Inc'),), (('commonName', 'Google Internet Authority G2'),)), 'version': 3, 'serialNumber': '297B797A0530FA58', 'notBefore': 'Mar 28 13:56:32 2018 GMT', 'notAfter': 'Jun 20 13:23:00 2018 GMT', 'subjectAltName': (('DNS', '*.google.com'), ('DNS', '*.android.com'), ('DNS', '*.appengine.google.com'), ('DNS', '*.cloud.google.com'), ('DNS', '*.db833953.google.cn'), ('DNS', '*.g.co'), ('DNS', '*.gcp.gvt2.com'), ('DNS', '*.google-analytics.com'), ('DNS', '*.google.ca'), ('DNS', '*.google.cl'), ('DNS', '*.google.co.in'), ('DNS', '*.google.co.jp'), ('DNS', '*.google.co.uk'), ('DNS', '*.google.com.ar'), ('DNS', '*.google.com.au'), ('DNS', '*.google.com.br'), ('DNS', '*.google.com.co'), ('DNS', '*.google.com.mx'), ('DNS', '*.google.com.tr'), ('DNS', '*.google.com.vn'), ('DNS', '*.google.de'), ('DNS', '*.google.es'), ('DNS', '*.google.fr'), ('DNS', '*.google.hu'), ('DNS', '*.google.it'), ('DNS', '*.google.nl'), ('DNS', '*.google.pl'), ('DNS', '*.google.pt'), ('DNS', '*.googleadapis.com'), ('DNS', '*.googleapis.cn'), ('DNS', '*.googlecommerce.com'), ('DNS', '*.googlevideo.com'), ('DNS', '*.gstatic.cn'), ('DNS', '*.gstatic.com'), ('DNS', '*.gvt1.com'), ('DNS', '*.gvt2.com'), ('DNS', '*.metric.gstatic.com'), ('DNS', '*.urchin.com'), ('DNS', '*.url.google.com'), ('DNS', '*.youtube-nocookie.com'), ('DNS', '*.youtube.com'), ('DNS', '*.youtubeeducation.com'), ('DNS', '*.yt.be'), ('DNS', '*.ytimg.com'), ('DNS', 'android.clients.google.com'), ('DNS', 'android.com'), ('DNS', 'developer.android.google.cn'), ('DNS', 'developers.android.google.cn'), ('DNS', 'g.co'), ('DNS', 'goo.gl'), ('DNS', 'google-analytics.com'), ('DNS', 'google.com'), ('DNS', 'googlecommerce.com'), ('DNS', 'source.android.google.cn'), ('DNS', 'urchin.com'), ('DNS', 'www.goo.gl'), ('DNS', 'youtu.be'), ('DNS', 'youtube.com'), ('DNS', 'youtubeeducation.com'), ('DNS', 'yt.be')), 'OCSP': ('http://clients1.google.com/ocsp',), 'caIssuers': ('http://pki.google.com/GIAG2.crt',), 'crlDistributionPoints': ('http://pki.google.com/GIAG2.crl',)}

print(x["subject"]["commonName"])

Upvotes: 0

Views: 53

Answers (3)

snakes_on_a_keyboard
snakes_on_a_keyboard

Reputation: 884

With the caveat that I would recommend being careful as this data structure indicates that nested tuples could have duplicate pairs:

>>> dict(map(lambda x: x[0], x['subject']))['commonName']
'*.google.com'

does the trick.

Upvotes: 0

Alaa Aqeel
Alaa Aqeel

Reputation: 645

x = {'subject': ((('countryName', 'US'),), (('stateOrProvinceName', 'California'),), (('localityName', 'Mountain View'),), (('organizationName', 'Google Inc'),), (('commonName', '*.google.com'),)), 'issuer': ((('countryName', 'US'),), (('organizationName', 'Google Inc'),), (('commonName', 'Google Internet Authority G2'),)), 'version': 3, 'serialNumber': '297B797A0530FA58', 'notBefore': 'Mar 28 13:56:32 2018 GMT', 'notAfter': 'Jun 20 13:23:00 2018 GMT', 'subjectAltName': (('DNS', '*.google.com'), ('DNS', '*.android.com'), ('DNS', '*.appengine.google.com'), ('DNS', '*.cloud.google.com'), ('DNS', '*.db833953.google.cn'), ('DNS', '*.g.co'), ('DNS', '*.gcp.gvt2.com'), ('DNS', '*.google-analytics.com'), ('DNS', '*.google.ca'), ('DNS', '*.google.cl'), ('DNS', '*.google.co.in'), ('DNS', '*.google.co.jp'), ('DNS', '*.google.co.uk'), ('DNS', '*.google.com.ar'), ('DNS', '*.google.com.au'), ('DNS', '*.google.com.br'), ('DNS', '*.google.com.co'), ('DNS', '*.google.com.mx'), ('DNS', '*.google.com.tr'), ('DNS', '*.google.com.vn'), ('DNS', '*.google.de'), ('DNS', '*.google.es'), ('DNS', '*.google.fr'), ('DNS', '*.google.hu'), ('DNS', '*.google.it'), ('DNS', '*.google.nl'), ('DNS', '*.google.pl'), ('DNS', '*.google.pt'), ('DNS', '*.googleadapis.com'), ('DNS', '*.googleapis.cn'), ('DNS', '*.googlecommerce.com'), ('DNS', '*.googlevideo.com'), ('DNS', '*.gstatic.cn'), ('DNS', '*.gstatic.com'), ('DNS', '*.gvt1.com'), ('DNS', '*.gvt2.com'), ('DNS', '*.metric.gstatic.com'), ('DNS', '*.urchin.com'), ('DNS', '*.url.google.com'), ('DNS', '*.youtube-nocookie.com'), ('DNS', '*.youtube.com'), ('DNS', '*.youtubeeducation.com'), ('DNS', '*.yt.be'), ('DNS', '*.ytimg.com'), ('DNS', 'android.clients.google.com'), ('DNS', 'android.com'), ('DNS', 'developer.android.google.cn'), ('DNS', 'developers.android.google.cn'), ('DNS', 'g.co'), ('DNS', 'goo.gl'), ('DNS', 'google-analytics.com'), ('DNS', 'google.com'), ('DNS', 'googlecommerce.com'), ('DNS', 'source.android.google.cn'), ('DNS', 'urchin.com'), ('DNS', 'www.goo.gl'), ('DNS', 'youtu.be'), ('DNS', 'youtube.com'), ('DNS', 'youtubeeducation.com'), ('DNS', 'yt.be')), 'OCSP': ('http://clients1.google.com/ocsp',), 'caIssuers': ('http://pki.google.com/GIAG2.crt',), 'crlDistributionPoints': ('http://pki.google.com/GIAG2.crl',)}
# ^_^ 
print(x["subject"][0][0])# type --> tuple('countryName', 'US')
print(dict(x["subject"][0])["countryName"]) 
print(dict(x["subject"][0]).get("countryName"))

Upvotes: 0

salparadise
salparadise

Reputation: 5825

What you are looking for is a tuple and not a dict. You can convert it to a dict by flattening the item with the tuples and converting each pair to a key/value and looking it up by key.

Using itertools.chain to flatten:

In [35]: import itertools

In [36]: dict(itertools.chain(*x['subject']))['commonName']
Out[36]: '*.google.com'

Or use next after flattening, and match on the name:

In [38]: next(val for name, val in itertools.chain(*x['subject']) if name == 'commonName')
Out[38]: '*.google.com'

Upvotes: 1

Related Questions