Raja G
Raja G

Reputation: 6673

Python3: TypeError: list indices must be integers or slices, not str

I have my data stored in json format. And by using json:load() I am reading the data.

What I am trying to do is based on argument passed , I am trying to extract specific part of Key:Value from the list and storing them into a new list for later processing.

Code

selected_env='mydev2'
server_list=[{'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}, {'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}]         
for item in server_list :
    host_list=[item for item in server_list[selected_env] if selected_env in server_list]

print(host_list)

And I am getting error as

TypeError: list indices must be integers or slices, not str

Note: I have achieved already one way of extraction as below

for item in server_list:
  for element in item :
    if element == selected_env :
       host_list=item[selected_env]  

even though its working, I thought of optimizing it and went to read some articles on list extraction and kind of stuck with above error.

Any help, greatly appreciated.

Upvotes: 1

Views: 30976

Answers (4)

khadija-djarraya
khadija-djarraya

Reputation: 25

One other option could be changing the for loop this way:

for item in range(len(server_list)):
   host_list = [item[selected_env] for item in server_list if selected_env in item]
host_list = list(itertools.chain(*host_list)) 

Upvotes: 0

Austin
Austin

Reputation: 26037

What you are doing wrong is you are accessing element in list server_list by selected_env which is a string.

server_list[selected_env]

The above statement caused your error. Instead you need to check if selected_env is in an item of server_list.

This should work:

selected_env='mydev2'
server_list=[{'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}, {'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102']}]         
for item in server_list :
    host_list = [item[selected_env] for item in server_list if selected_env in item]
host_list = list(itertools.chain(*host_list)) # To convert sub-list into flat
# assumed as import itertools included    

print(host_list)
# [['192.168.56.102', '192.168.56.102', '192.168.56.102']]                                                

Upvotes: 3

Laurent H.
Laurent H.

Reputation: 6526

If your input data is necessarily a list of dictionaries, I suggest you to first convert it to a single dictionay, using a nice dict comprehension, as follows:

selected_env='mydev2'
server_list=[{'mydev': ['192.168.56.101', '192.168.56.102', '192.168.56.103']}, {'mydev2': ['192.168.56.104', '192.168.56.105', '192.168.56.106']}] 

server_dict = {k:v for d in server_list for k,v in d.items()}
host_list = server_dict[selected_env]

print(host_list)

Note:
d.items() returns a list containing all the tuples (key,value) of the dictionary d.
So for my code, in the dict comprehension:

  1. On 1st iteration, d equals {'mydev': ['192.168.56.101', '192.168.56.102', '192.168.56.103']} and d.items() equals [('mydev',['192.168.56.101', '192.168.56.102', '192.168.56.103'])]

  2. On 2nd iteration, d equals {'mydev2': ['192.168.56.104', '192.168.56.105', '192.168.56.106']} and d.items() equals [('mydev2',['192.168.56.104', '192.168.56.105', '192.168.56.106'])]

Upvotes: 4

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

Why use a list of dicts when a simple dict would work ???

servers={
   'mydev': ['192.168.56.102', '192.168.56.102', '192.168.56.102'], 
   'mydev2': ['192.168.56.102', '192.168.56.102', '192.168.56.102'],
   }

host_list = servers["mydev2"]

Dict lookups are O(1) and extremely optimized (dicts being used everywhere in Python internals). A list lookup is O(N).

Upvotes: 3

Related Questions