Question about accessing indices in nested lists - python

I was learning about Deep Learning in Kaggle through an exercise and this confused me. In order to write a code for checking whether something was a hot dog or not, there was a list of predictions, with each element being the most likely prediction for what a different image was. So the overall list was :
[
[('n07697537', 'hotdog', 0.8770528)],
[('n07697537', 'hotdog', 0.9659182)],
[('n07579787', 'plate', 0.7972369)],
[('n07583066', 'guacamole', 0.9996675)]
]
And one element is:
[('n07697537', 'hotdog', 0.9659182)]
So in order to check whether an image is most likely a hotdog, I'd have to get that second field, the label. But I ran into some syntax issues trying to access the field inside the nested list.
So I tried accessing the first element's label as an example (decoded is the name of the outer list) with print(decoded[0][1]). This didn't work. So I checked the sample solution after failing to figure out how to access the element cleanly without having to do something convoluted.
The sample code used
labels = [d[0][1] for d in decoded]
And that successfully makes a list of the labels. I tried to do something similar before checking the solution but I was slightly off, I tried the singular version of this by setting d = decoded[0] , and I got a list of length 1 with the three elements, like the element example earlier. What I found confusing is that d[0][1] works to give the me label, but decoded[0][1] does not. Why?

You need to work on tuples :
decoded = [[('n07697537', 'hotdog', 0.8770528)], [('n07697537', 'hotdog', 0.9659182)], [('n07579787', 'plate', 0.7972369)], [('n07583066', 'guacamole', 0.9996675)]]
d = [x for y in decoded for x in y]
labels = [d[0][1] for d in decoded]
This script gives:
['hotdog', 'hotdog', 'plate', 'guacamole']

If you would like to access the first element's label aka 'hotdog' in the first tuple, you need to print(decoded[0][0][1]) where the [1] in decoded[0][0][1] is the 2nd element in the tuple (0-indexed), the right hand [0] is the tuple itself, and the left hand [0] is the inner list.
Some background: there is actually a list enclosing other lists of tuples in your example shown as [[()],[()],[()]] where () is a tuple and [] is a list. You could in theory have multiple tuples in each inner list like [[(),(),()],[(),()],[()]] etc. However, you access values within tuples the same way as you do with lists, using indices, hence the confusion.
The code [d[0][1] for d in decoded] works because d is actually just a list of tuples (though only one tuple is in the list in this case).

Related

Someone please explain what the for loop does / its meaning for this section of code?

I'm learning python and I'm trying to understand what the for loop means. My assignment is to understand and comment the full code out. I know that the first two lines of code take an input. Can someone tell me what the next lines of code mean? The for loop is extremely confusing. By the way, let's say the input for j_t is 1, 3, 5 and the input for d_t is 2, 4, 6. Hopefully that helps.
# to take inputs
j_t = list(map(int, input("Process times: ").split(",")))
d_t = list(map(int, input("Job Due Dates: ").split(",")))
dict_spt = {}
dict_edd = {}
for i in range(len(j_t)):
dict_spt[int(j_t[i])] = int(d_t[i])
dict_edd[int(d_t[i])] = int(j_t[i])
The above is a segment of the full code. I ran the full code and it allows me to put in input but I need to understand what the for loop actually does/means in plain english.
Python input give you a string input, j_t and d_t are lists made from your inputs but it is still as string in the lists. for loop is actually iterating on your inputs to create dictionnaries which allow you to get j_t from a d_t value and vice versa and in a same time is casting all inputs to integers to make it easier to use i guess.
Hope it is clear enough
The first 2 lines of code take in an input and creates a list out of them (j_t and d_t).
The next 2 lines initializes a dictionary object (dict_spt and dict_edd).
The for loop iterates from 0 to the length of j_t - 1 = 2 which means that it iterates over all the indices of the items in j_t (1,3,5). The first line in the dictionary puts the key-value pair of int(j_t[0]) = 1 , int(d_t[0]) = 2 into the dict_spt dictionary. And it also adds in the key-value pair of int(d_t[0]) = 2 , int(j_t[0]) = 1 (which is same like the first one but reversed) into the dict_edd dictionary. It does this until the last element (5) is reached.
Hopefully this explanation is clear.
The for loop is your standard construct for iterating through arrays of data. I'll walk you through the whole code.
So in python you have multiple types of, let's call them "array like" structures. In this example you've shown, you have lists and dictionaries. Lists are very similar to standard arrays, where as dictionaries are an "array" of key value pairs.
Now the first two lines take your comma separated inputs and turn them into lists.
Then you create two empty dictionaries - that's indicated by the curly brackets, those are used for defining dictionaries.
Then you have the actual for loop - the best way to read the for line would be:
"For each element i in the range() from zero to the length of thej_t list, do the following"
Important to note that i or whatever you put after the for keyword is a variable that is created on the fly simply for the purpose of iterating through the piece of data you're iterating.
And then in the for loop what you are doing is adding a new record to each dictionary where the key and the value are the integer value of each list element.
Arrays and lists have indexes for every element inside of them so all the standard for loop needs is a numerical range which would represent every index in the structure you're iterating through.
Hope this was clear enough.

Refer to a list in Python from within the [ ] operator

While trying to optimize a one-liner that extracts values from a list of dicts (all strings that come after keyword/ til the next /) I got stuck in the following:
imagine this list of dicts:
my_list = [{'name':'val_1', 'url':'foo/bar/keyword/bla_1/etc'}.......{'name':'val_z', 'url':'foo/bar/keyword/bla_n/etc'}]
The numbers in val_ and bla_ are not related.
I am trying to extract all the bla_x (they could be anything, no pattern possible) words using list comprehension for 0 < x < n+1. I managed to get the index of those elements in the split string
[d['url'].split('/').index('keyword') + 1 for d in my_list]
But what I need is to access that value and not only its index, so I thought about something like this:
[d['url'].split('/')[the_resulting_split_list.index('keyword') + 1] for d in my_list]
As far as my knowledge go, that seems impossible to do. Is there an alternative way to reach my goal of getting an output of ['bla_1', 'bla_2', ....., 'bla_n'] without having to run the split('/') operation twice in the list comprehension?
Let's not care about exceptions for now and assume input data is always correct.

Combining three different list in python

Thank you for looking at my issue.
I'm trying to compare cells from three csv files to make sure they are exactly the same info. the cells in the csv can contain names, dates or ID numbers. All have to match.
compile = []
for a in Treader,Vreader,Dreader:
for b in a:
compile.append(b[0])
However, the number of variables will fluctuate and I don't want to keep adding index splicing every time. see "complie.append(b[0])" . The question now what way can I construct this to give me a random amount of variables and random number of indexes based on the length "len" of the original list. can i use the range function for that? not sure how i can create something like this.
The current question I have is
List = [[sally,john,jim], [sally,john,jim], [sally,john,jim]]
If I have the list above how could I get it to show
List =[sally,sally,sally]
List1 = [john,john,john]
List2 = [jim,jim,jim]
Also I want to be able to come up with unlimited number of list based on the length of this list that is inside the list. In this case its 3 for three names.
Some of my list has 30 some has 5 so its important I can assign it without having to type list1 to list 30 and manually assign each one.
you may use:
compile = list(zip(Treader,Vreader,Dreader))
this will create a list of tuples, a tuple will have like (sally,john,jim)
after your edit
you may use:
list(zip(*List))
output:
[('sally', 'sally', 'sally'), ('john', 'john', 'john'), ('jim', 'jim', 'jim')]

Enumerate - Python loop

I have two lists with just one element as follows(each of these two lists always contains only one element):
Vnew = [600]
Newoints2 = [(2447,3480)]
I'm trying to bring both of them together using the following code sample:
for i, key in enumerate(Vnew2):
pos3[key] = newpoints2[i]
But this returns an error as IndexError: list assignment index out of range
I actually did this one for other lists which have more than one element. It worked fine and got the output as {0:(1245,674),1:(2457,895),...}
Can someone find the mistake here?
It looks like you are trying to concatenate the lists into a new list. You don't always need to enumerate through the list.
You will be able to do this by Vnew + Newoints2

Please tell this newbie what the difference is between these two list outputs?

I am struggling with something and have tracked it down to the difference between two lists inside my code: from the Python Debugger:
(Pdb) Values
['Thing1', 'Thing2', 'Thing3']
(Pdb) values2
[['Thing1', 'Thing2', 'Thing3']]
I do NOT want the double brackets, what does this mean and how do I get rid of them?
'Values' creation was by:
values = ['Thing1','Thing2','Thing3']
'Values2' creation was by:
for report in Report.objects.filter(id=id):
values2.append([str(report.name), str(report.subject), str(report.description)])
Why am I getting this difference and how can I get Values2 to look like Values ?
Don't think of it as "double brackets". Think of it as two sets of single brackets, one inside the other. A set of brackets means you have a list. Two sets of single brackets means you have two lists. One set of single brackets inside another means you have a list inside another list.
This is because the value you appended was a list, because you did values2.append([...]). The [...] is a list, so you appended a list; that is, you put a nested list inside values2.
If you don't want that, you could do:
values2.extend([str(report.name), str(report.subject), str(report.description)])
extend will add each element of the list as a separate element, instead of adding the whole list as one element. (Whether this will actually work in the larger context of your program depends on what you actually do with values2.)
values2 is a list with a single element that is a list.
You are appending a list to a list. What you want to do is extend the values2 list:
for report in Report.objects.filter(id=id):
values2.extend([str(report.name), str(report.subject), str(report.description)])
If you look at your loop
for report in Report.objects.filter(id=id):
values2.append( [ str(report.name), str(report.subject), str(report.description) ] )
you can see that what you are appending to values2 is the the list
[ str(report.name), str(report.subject), str(report.description) ]
so values2 - assuming it was empty in the first place - now has one element, being that list, and it looks like
[
['Thing1', 'Thing2', 'Thing3'],
]
as you described.
If you want to append the three strings instead then you have to do it one at a time, like this
for report in Report.objects.filter(id=id):
values2.append(str(report.name))
values2.append(str(report.subject))
values2.append(str(report.description))
or you could use extend instead, but I believe that would be less clear.

Categories

Resources