Extracting the last items from nested lists in python [duplicate] - python

This question already has answers here:
Python - get the last element of each list in a list of lists
(5 answers)
Closed 2 years ago.
I have some nested lists. I want to extract the last occurring element within each sublist (eg 'bye' for the first sublist). I then want to add all these last occurring elements ('bye', 'bye', 'hello' and 'ciao') to a new list so that I can count them easily, and find out which is the most frequently occurring one ('bye).
The problem is that my code leaves me with an empty list. I've looked at Extracting first and last element from sublists in nested list and How to extract the last item from a list in a list of lists? (Python) and they're not exactly what I'm looking for.
Thanks for any help!
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
# Make a new list of all of the last elements in the sublists
new_list = []
for sublist in my_list:
for element in sublist:
if sublist.index(element) == -1:
new_list.append(element)
# MY OUTPUT
print(new_list)
[]
# EXPECTED OUTPUT
['bye', 'bye', 'hello', 'ciao']
# I would then use new_list to find out what the most common last element is:
most_common = max(set(new_list), key = new_list.count)
# Expected final output
print(most_common)
# 'bye'

You can call the last element of a list by calling the index -1, e.g. sublist[-1]. The following code should give you your expected result:
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
new_list = list()
for sublist in my_list:
new_list.append(sublist[-1])
print(new_list)
or as Risoko pointed out, you can do it in one line, so the code should look like
my_list = [['hello', 'bye', 'bye'], ['hello', 'bye', 'bye'], ['hello', 'hello', 'hello'], ['hello', 'bye', 'ciao']]
new_list = [sublist[-1] for sublist in my_list]
print(new_list)

You are looking for this:
for sublist in my_list:
new_list.append(sublist[-1])
The index -1 does not "really exist", it is a way to tell python to start counting from the end of the list. That is why you will not get a match when looking for -1 like you do it.
Additionally, you are walking over all the lists, which is not necessary, as you have "random access" by fetching the last item as you can see in my code.
There is even a more pythonic way to do this using list comprehensions:
new_list = [sublist[-1] for sublist in my_list]
Then you do not need any of those for loops.

output = [sublist[-1] for sublist in my_list]

Related

list in list, search in an another list [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last month.
Improve this question
I have a first list, containing string lists and a second list containing strings. I want that when a string from the first list is found in the second, the string from the second is returned and the search resumes at the next string from the first list.
list1 = [
['test', 'string'],
['hello', 'world']
['good', 'morning','everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
If list1[0][0] is in list2[0], then return list2[0] and go to list1[1] (don't want to test list1[0][1]).
I've tried nesting for loops inside other for loops with break and if conditions but can't get the solution.
If the length of lists is the same, the code should be something like this:
list1 = [
['test', 'string'],
['hello', 'world'],
['good', 'morning', 'everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
answer = []
for l1 in range(len(list1)):
for item in list1[l1]:
if item in str(list2[l1]):
answer.append(item)
break
print(*answer)
and output will be
test
Hope this helped! :D
First, here are some tips for solving problems like this in the future:
First, the format of your input data is pretty strange (in my opinion), so I'd really recommend trying to flatten everything out -- this may or may not be possible depending on the larger structure of your program, so if you can't actually do that, then no big deal. Something like:
list1 = [ ['test', 'string'], ['hello', 'world'], ['good', 'morning', 'everyone'] ]
list2 = ['test is here', 'hi everyone', 'world of code']
is already easier to work with from a data processing standpoint, and that's just from flattening list2.
Second, conceptually, you have to have two loops going on here -- the first is to iterate through list1 (so if you find a match in list2, you can return the match and move onto the next member of list1), and another to go through the individual elements of list1, since a string in list2 could match on any one of the strings from the inner lists in list1 (i.e. a string in list2 could be matched either by 'test' or 'string').
With that said, here's a (pretty inefficient) solution to your problem:
def check_long_str(long_strings, check_list):
for check in check_list: #iterate over individual strings in each inner list of list1
for long_string_item in long_strings: #look for a match in list2
long_string = long_string_item[0] #weird format
if check in long_string:
print('"{}" found "{}"'.format(check, long_string))
return long_string
return None
def check_for_strings(search_strings, long_strings):
toReturn = set()
for search_list in search_strings: #iterate over inner lists of list1
found_str = check_long_str(long_strings, search_list)
if found_str is not None:
toReturn.add(found_str)
return toReturn
print(check_for_strings(list1, list2))
Output:
"test" found "test is here"
"world" found "world of code"
"everyone" found "hi everyone"
set(['test is here', 'hi everyone', 'world of code'])
So there was an error in the code you gave. I found an issue in the code you gave. There is a typo which is a missing "," after one of the lists. This is right after the:
['hello', 'world']
list in list1.
Although there may be better ways to loop through a nested list, this is how I would do it.
list1 = [
['test', 'string'],
['hello', 'world'],
['good', 'morning', 'everyone']]
list2 = [
['test is here'],
['hi everyone'],
['world of code']]
found_words = []
for i in range(len(list1)):
for x in range(len(list1[i])):
for z in list2:
for y in z:
teststring = y.split()
for j in teststring:
if j in list1[i][x]:
found_words.append(j)
break
print(found_words)
Output:
['test', 'world', 'everyone']
Hopefully this helps!

How can I merge a list with a nested list?

I have two lists. The first one is a simple list with one entry:
l = [hello]
The second one is a nested list, with several thousand entries
i = [[world, hi],
[world, hi],
[world, hi],
[world, hi]]
Now I want to insert the entry from list l into the nested lists of i like this:
i = [[hello, world, hi],
[hello, world, hi],
[hello, world, hi],
[hello, world, hi]]
How can I do this?
You can use list comprehension to achieve that
i = [l+x for x in i]
Just use the insert method on each sublist in i.
for sublist in i:
sublist.insert(0, l[0])
If you don't want to modify i in place, and would prefer to build a new list, then
i = [[l[0], *sublist] for sublist in i]
simple: [[*l,*el] for el in i]
Output:
[['hello', 'world', 'hi'],
['hello', 'world', 'hi'],
['hello', 'world', 'hi'],
['hello', 'world', ' hi']]
I guess the benefits is that no matter how many elements you have in l, they will all be put in front of the stuff in i
Just add the element to the list you want
l = ["hello"]
i = [["world", "hi"],
["world", "hi"],
["world", "hi"],
["world", "hi"]]
x = []
for y in i:
x.append(l+y)
x
output:
[['hello', 'world', 'hi'],
['hello', 'world', 'hi'],
['hello', 'world', 'hi'],
['hello', 'world', 'hi']]
I believe something like this should do the trick:
l = ['hello']
i = [['world', 'hi'],
['world', 'hi'],
['world', 'hi'],
['world', 'hi']]
for j in i:
for k in l:
j = j.append(k)
I'm just iterating through your list i, nesting another for loop to iterate through the simpler list l (to account for the case whereby it has multiple elements), and simply appending each entry in l to the current list in i.

Python: Remove a single entry in a list based on the position of the entry [duplicate]

This question already has answers here:
How to remove an element from a list by index
(18 answers)
Closed 7 years ago.
Is there an easy way to delete an entry in a list? I would like to only remove the first entry. In every forum that I have looked at, the only way that I can delete one entry is with the list.remove() function. This would be perfect, but I can only delete the entry if I know it's name.
list = ['hey', 'hi', 'hello', 'phil', 'zed', 'alpha']
list.remove(0)
This doesn't work because you can only remove an entry based on it's name. I would have to run list.remove('hey'). I can't do this in this particular instance.
If you require any additional information, ask.
These are methods you can try:
>>> my_list = ['hey', 'hi', 'hello', 'phil', 'zed', 'alpha']
>>> del my_list[0]
>>> my_list = ['hey', 'hi', 'hello', 'phil', 'zed', 'alpha']
>>> if 'hey' in my_list: # you're looking for this one I think
... del my_list[my_list.index('hey')]
...
>>> my_list
['hi', 'hello', 'phil', 'zed', 'alpha']
You can also use filter:
my_list = filter(lambda x: x!='hey', my_list)
Using list comprehension:
my_list = [ x for x in my_list if x!='hey']
First of all, never call something "list" since it clobbers the built-in type 'list'. Second of all, here is your answer:
>>> my_list = ['hey', 'hi', 'hello', 'phil', 'zed', 'alpha']
>>> del my_list[1]
>>> my_list
['hey', 'hello', 'phil', 'zed', 'alpha']
Lists work with positions, not keys (or names, whatever you want to call them).
If you need named access to your data structure consider using a dictionary instead which allows access to its value by using keys which map to the values.
d = {'hey':0, 'hi':0, 'hello':0, 'phil':0, 'zed':0, 'alpha':0}
del d['hey']
print(d) # d = {'alpha': 0, 'hello': 0, 'hi': 0, 'phil': 0, 'zed': 0}
Otherwise you will need to resort to index based deletion by getting the index of the element and calling del alist[index].
To add to the poll of answers..how about:
>>> my_list = ['hey', 'hi', 'hello', 'phil', 'zed', 'alpha']
>>> my_list=my_list[1:]
>>> my_list
['hi', 'hello', 'phil', 'zed', 'alpha']

Making a new list from an existing list

Basically just looking if there is an easy way to reverse the list.
People were getting to confused with my original question.
This was the list: words = ['hey', 'hi', 'hello', 'hi']
How to reverse it (to a new list) and only add to new list if it is not already in it.
This snippet iterates through the list of words in reverse; and adds new unique entries to a new list.
words = ['hey', 'hi', 'hello', 'hi']
result = []
for word in reversed(words):
if word not in result:
result.append(word)
print(result)
Output
['hi', 'hello', 'hey']
Converting the first list to a set() ensures duplicates are removed. Then the set is converted to a reversely sorted list.
final_lst = sorted(set(words), reverse=True)

Convert certain values in list to int

I have a list of lists and I want to convert the second value in each list to an int since it is currently a string
[['hello','how','are','you','1'],['hello','how','are','you','2']]
I am trying to convert index 4 to an int in each list within this larger list but when I do
for hi in above:
int(hi[4])
It is just returning the int when I print the list and not the entire list.
Just traverse it and convert it using the int() function for every 4th element in every list inside :
for li in my_list:
li[4] = int(li[4])
This list comprehension is one way to do it:
a_list = [[int(a) if item.index(a) == 4 else a for a in item] for item in a_list]
Demo:
>>> a_list = [['hello','how','are','you','1'],['hello','how','are','you','2']]
>>> a_list = [[int(a) if item.index(a) == 4 else a for a in item] for item in a_list]
>>> a_list
[['hello', 'how', 'are', 'you', 1], ['hello', 'how', 'are', 'you', 2]]
>>>

Categories