-2

I have this code that errors out in python3:

self.instance_id = get_instance_metadata(data='meta-data/instance-id').keys()[0]

TypeError: 'dict_keys' object is not subscriptable

I changed my code and I get different error (I guess I need more experience):

self.instance_id = get_instance_metadata(list(data='meta-data/instance-id').keys())[0]

TypeError: list() takes no keyword arguments
wjandrea
  • 28,235
  • 9
  • 60
  • 81
  • 1
    Just `list(get_instance_metadata(data='meta-data/instance-id').keys())[0]` – Mechanic Pig Dec 02 '22 at 00:11
  • Please take the [tour] and read [ask]. SO is a Q&A site, but you haven't asked a question. It looks like you want to ask, "How can I fix this?", to which the answer is, you put `list()` in the wrong place; it should be `list(get_instance_metadata(...).keys())[0]`. Although, I'm not sure how helpful that is, because it's kind of strange to get the first element from a dict. Plus, if the dict could be very large, converting it to `list` could be wasteful. Beware the [XY problem](https://meta.stackexchange.com/q/66377/343832). – wjandrea Dec 02 '22 at 00:12
  • 1
    The second attempt failed due to a typo, but the first one was not a typo, and the underlying question "How do I get the first key from a `dict`?" is a reasonable question. That said, I should have caught that it was [a duplicate](https://stackoverflow.com/q/30362391/364696). – ShadowRanger Dec 02 '22 at 00:17
  • 1
    @wjandrea: With modern insertion-ordered `dict`s, the concept of "first key in a `dict`" is more useful than it used to be. Pre-3.6, yeah, "first key" really meant "arbitrary key", but it's more meaningful than that now. – ShadowRanger Dec 02 '22 at 00:17

1 Answers1

0

.keys() is a set-like view, not a sequence, and you can only index sequences.

If you just want the first key, you can manually create an iterator for the dict (with iter) and advance it once (with next):

self.instance_id = next(iter(get_instance_metadata(data='meta-data/instance-id')))

Your second attempt was foiled by mistakes in where you performed the conversion to list, and should have been:

self.instance_id = list(get_instance_metadata(data='meta-data/instance-id').keys())[0]  # The .keys() is unnecessary, but mostly harmless

but it would be less efficient than the solution I suggest, as your solution would have to make a shallow copy of the entire set of keys as a list just to get the first element (big-O O(n) work), where next(iter(thedict)) is O(1).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271