Flattening list of lists [duplicate] - python

This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
Closed 5 years ago.
Hey I am having trouble trying to make a list of list into just one please help:
I want:
a = [['a'], 'b', 'c', 'd', 'e']
To become:
a = ['a', 'b', 'c', 'd', 'e']
Thanks

As long as your lists can't be nested more than one deep, you could do:
def flatten(lst):
for el in lst:
if isinstance(el, list):
yield from el
else:
yield el
Then call list on the result if you actually need it as a list (usually an iterator will do).
a = [['a'], 'b', 'c', 'd', 'e']
flat_a = flatten(a) # not a list, but an iterator that returns flat values
flat_a_as_lst = list(flat_a) # actually a list

Try to iterate all sub-lists of the list. For your list a:
a = [['a'], 'b', 'c', 'd', 'e']
flat_a = [subitem for item in a for subitem in (item if isinstance(item, list) else [item])]
Edit: considered Adams's comment.

Related

Function that takes list input, and returns a new list containing only the elements in that are repeated [duplicate]

This question already has answers here:
How do I find the duplicates in a list and create another list with them?
(42 answers)
Closed 5 months ago.
>>> list_a = ['a', 'b', 'c', 'c']
>>> get_repeated(list_a)
['c']
What would be the most pythonic way to do function get_repeated()?
this should work
from collections import Counter
list_a = ['a', 'b', 'c', 'c']
count = Counter(list_a)
output = [key for key, val in count.items() if val > 1]
print(output)
>>> ['c']

Get key from a list of values in dictionary? [duplicate]

This question already has answers here:
Get key by value in dictionary
(43 answers)
How to implement an efficient bidirectional hash table?
(8 answers)
Python: How to search a nested list using recursion
(5 answers)
Closed 8 months ago.
Let's say I have:
ref = ['<var>', '<id>', '<expr>']
val = [['a', 'b', 'c'], 'a', '1+1']
dicio = dict(zip(ref, val))
now, I know that by doing
list(dicio.keys())[list(dicio.values()).index('a')]
It returns <id>. But let's say that you only had one value associated per key, so
val = [['a', 'b', 'c'], 'b', '1+1']
How could I get <var> without listing ['a', 'b', 'c']?
Thank you.
Just replace "a" value by the list ['a', 'b', 'c']:
print(list(dicio.keys())[list(dicio.values()).index(['a', 'b', 'c'])])
You will get as output the value associated with the index you inserted before:
<var>
Or you can use list comprehension to traverse the list of dict values:
ref = ['<var>', '<id>', '<expr>']
val = [['a', 'b', 'c'], 'a', '1+1']
dicio = dict(zip(ref, val))
selectedVal = list(i for i in list(dicio.values()) if "a" in i)[0]
print(list(dicio.keys())[val.index(selectedVal)])
Which outputs the same as the previous solution.

How to add all items at index to new list [duplicate]

This question already has answers here:
How do I iterate through two lists in parallel?
(8 answers)
Closed 3 years ago.
I am currently trying to re-sort a list I got from parsing a website.
I have tried everything but I don't think I found the best solution to my problem.
Let's say we have the following list:
my_list = [['a', 'b', 'c'], ['a', 'b', 'c']]
What I am trying to convert it to:
new_list = [['a', 'a'], ['b', 'b'], ['c', 'c']]
I came up with the following loop:
result = [[], [], []]
for sublist in my_list:
for i in range(0, len(sublist)):
result[i].append(sublist[i])
print(result)
# output: [['a', 'a'], ['b', 'b'], ['c', 'c']]
My method is not the best I assume and I am searching for the most pythonic way to do it if you know what I'm saying.
The Python builtin function zip() is your friend here.
From the official documentation, it
returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.
What that means is that given two lists, zip(list1, list2) will pair list1[0] with list2[0], list1[1] with list2[1], and so on.
In your case, the lists you want to zip together are inside another list, my_list, so you can unpack it with *my_list. Since zip() returns an iterator, you want to create a list out of the return value of zip(). Final solution:
new_list = list(zip(*my_list))
I have written a code which exactly does what you want. You should use map after zip to convert tuples to lists.
Code:
my_list = [['a', 'b', 'c'], ['a', 'b', 'c']]
my_new_list = list(map(list, zip(my_list[0], my_list[1])))
print(my_new_list)
Output:
>>> python3 test.py
[['a', 'a'], ['b', 'b'], ['c', 'c']]

How to combine every element of a list to the other list? [duplicate]

This question already has answers here:
Element-wise addition of 2 lists?
(17 answers)
Closed 5 years ago.
Suppose there are two lists:
['a', 'b', 'c'], ['d', 'e', 'f']
what I want is:
'ad','ae','af','bd','be','bf','cd','ce','cf'
How can I get this without recursion or list comprehension? I mean only use loops, using python?
The itertools module implements a lot of loop-like things:
combined = []
for pair in itertools.product(['a', 'b', 'c'], ['d', 'e', 'f']):
combined.append(''.join(pair))
While iterating through the elements in the first array, you should iterate all of the elements in the second array and push the combined result into the new list.
first_list = ['a', 'b', 'c']
second_list = ['d', 'e', 'f']
combined_list = []
for i in first_list:
for j in second_list:
combined_list.append(i + j)
print(combined_list)
This concept is called a Cartesian product, and the stdlib itertools.product will build one for you - the only problem is it will give you tuples like ('a', 'd') instead of strings, but you can just pass them through join for the result you want:
from itertools import product
print(*map(''.join, product (['a','b,'c'],['d','e','f']))

Removing element messes up the index [duplicate]

This question already has answers here:
Loop "Forgets" to Remove Some Items [duplicate]
(10 answers)
Closed 8 years ago.
I have a simple question about lists
Suppose that I want to delete all 'a's from a list:
list = ['a', 'a', 'b', 'b', 'c', 'c']
for element in list:
if element == 'a':
list.remove('a')
print list
==> result:
['a', 'b', 'b', 'c', 'c', 'd', 'd']
I know this is happening because, after I remove the first 'a', the list index gets
incremented while all the elements get pushed left by 1.
In other languages, I guess one way to solve this is to iterate backwards from the end of the list..
However, iterating through reversed(list) returns the same error.
Is there a pythonic way to solve this problem??
Thanks
One of the more Pythonic ways:
>>> filter(lambda x: x != 'a', ['a', 'a', 'b', 'b', 'c', 'c'])
['b', 'b', 'c', 'c']
You should never modify a list while iterating over it.
A better approach would be to use a list comprehension to exclude an item:
list1 = ['a', 'a', 'b', 'b', 'c', 'c']
list2 = [x for x in list1 if x != 'a']
Note: Don't use list as a variable name in Python - it masks the built-in list type.
You are correct, when you remove an item from a list while iterating over it, the list index gets out of sync. What both the other existing answers are hinting at is that you need to create a new list and copy over only the items you want.
For example:
existing_list = ['a', 'a', 'b', 'c', 'd', 'e']
new_list = []
for element in existing_list:
if element != 'a':
new_list.append(element)
existing_list = new_list
print existing_list
outputs: ['b', 'c', 'd', 'e']

Categories