This question already has answers here:
Flatten an irregular (arbitrarily nested) list of lists
(51 answers)
Closed 6 months ago.
I try to make flat list. Now I have list:
L=['aa',['bb','cc']]
and I try:
L=['aa',['bb','cc']]
new=[]
for i in L:
print i
new+=i
print new
and I got:
'aa'
['bb','cc']
['a','a','bb','cc']
Why in print i=0 = 'aa' and in new+=i i=0 is only 'a'?
How i could get list ['aa','bb','cc']?
In general, meaning when you don't know the depth of the original list, this should work:
L=['aa',['bb','cc', ['dd', 'ee']], 'ff']
new = []
for l_item in L:
stack = [ l_item ]
while stack:
s_item = stack.pop(0)
if isinstance(s_item, list):
stack += [ x for x in s_item ]
else:
new.append(s_item)
print new
This gives:
['aa', 'bb', 'cc', 'dd', 'ee', 'ff']
Well, don't forget that strings are iterable in Python.
>>> new = []
>>> new += 'aa'
>>> print new
['a', 'a']
To be sure of adding what you want, you can proceed this way:
>>> L = ['aa',['bb','cc']]
>>> new = []
>>> for e in L:
... new.extend(e if type(e) == list else (e,))
>>> print new
['aa', 'bb', 'cc']
Seriously,
P.S. You can look at this post ... for more information.
This happens because you iterate over 'aa', basically treating it like it was ['a', 'a'].
If you want to avoid iterating over strings, you can look at the type:
for i in L:
if isinstance(i, list):
new += i
else:
new.append(i)
See this question for more details and how to do it recursively:
Flatten (an irregular) list of lists
Related
I'm just wondering how to convert a list of strings into a nested list? without module import.
for example:
input ["ABC","1","x","y","z"]
output ["ABC","1",["x","y","z"]]
In this particular case you could do this:
mylist = ["ABC","1","x","y","z"]
offset = 2
newlist = mylist[:offset] + [mylist[offset:]]
print(newlist)
Output:
['ABC', '1', ['x', 'y', 'z']]
Try:
mylist = ["ABC","1","x","y","z"]
def nest(mylist, n):
"""Nests list from nth element"""
nest = [x for x in mylist[n:]]
mylist = mylist[:n]
mylist.append(nest)
return mylist
nest(mylist, 2)
This question already has answers here:
Removing duplicate characters from a string
(15 answers)
Closed 2 years ago.
I have a list l = ['AAB', 'CAA', 'ADA'] . I want to get the following list without duplicated characters new_l = ['AB','CA','AD']. I am trying to iterate on a nested loop but I'm not sure this is the best way to accomplish this. here is my try:
new_l = []
for i in range(0,len(l)-1):
for j in range(0,len(l)-1):
if l[i][j] != l[i+1][j+1]:
new_l = ..............
Can someone help me on how to get a set by iterating over every element of this list of strings ?
You can easily do it, since a string is also a list.
strl = ['AAB', 'CAA', 'ADA']
new_strl = []
for s in strl:
new_strl.append("".join(set(s)))
print(new_strl)
Set can mess order of characters. Better use OrderedDict:
from collections import OrderedDict
strl = ['AAB', 'CAA', 'ADA']
result = ["".join(OrderedDict.fromkeys(s)) for s in strl]
l = ['AAB', 'CAA', 'ADA']
new_l = [''.join(sorted(set(x))) for x in l]
#op
['AB', 'AC', 'AD']
I have a list is a = ['R','R','R','B','R','B','B','S','S']. my goal is to delete repeat 'R's and 'S's and then delete the 'B's (if there is only one R or S, just keep it). Therefore, I want the output to be ['R','R','S'], but mine is ['R', 'S'].
Can anyone help me take look my code? Thank you
This is my code
a = ['R','R','R','B','R','B','B','S','S'] # create a list to store R S B
a = [x for x in a if x != 'B'] # Delete all the B's
new_list = [] # create another list to store R and S without repeat
last = None
for x in a:
if last == x and (len(new_list) == 0 or new_list[-1] != x):
new_list.append(last)
last = x
print(new_list)
My output is this
['R', 'S']
but I want this
['R','R','S']
You could use itertools.groupby to group the elements first, then delete the B values:
from itertools import groupby
a = ['R','R','R','B','R','B','S','S'] # create a list to store R S B
[k for k, v in groupby(a) if k != 'B']
Result:
['R', 'R', 'S']
You could try this. This creates a new list without anything that is a repeat, and no 'B's.
a = ['R','R','R','B','R','B','B','S','S']
new_list = [] # create another list to store R and S without repeat
last = None
for x in a:
if last != x and x!='B':
new_list.append(x)
last = x
print(new_list)
Another option is to use a list comprehension:
a = ['R','R','R','B','R','B','B','S','S']
new_list = [ x for i,x in enumerate(a) if (a[i-1] != x and x!='B') or (i==0) ]
print(new_list)
Output from either example is the same:
['R', 'R', 'S']
Neither of these options require an import. However, I think the groupby code given by Mark Meyer is what I'd use in most cases.
You can use fromkeys in this case.
mylist = ["a", "b", "a", "c", "c"]
mylist = list(dict.fromkeys(mylist))
print(mylist) # ['a', 'b', 'c']
I thought I had successfully created and filtered a list of lists using regular expression in python. However, when I attempt to index the lists I just index the first item in each of the lists. Upon closer inspection I noticed that I don't have any commas between my lists. I'm wondering how I can turn each of these individual lists into a list of lists?
I want to do this so that I can reference the different lists and state whether the lists meets a specific criteria.
import re
list_of_strings = ['''<z><x><c></v></b></n>''',
'''<paa>mnb<ore>mnbczx</bar><e>poiuy</e></paa>''',
'''<paa><ore></lan></ore></paa>''',
'''<paa><ore></ore></paa></paa>''',
'''<paa><ore></paa></ore>''']
def valid_html(list_of_strings):
matches = [[s] for s in list_of_strings]
lst = []
for item in matches:
tagsRegex = re.compile(r'(<.{0,3}>|</.{0,3}>)')
lst = (tagsRegex.findall(str(item)))
find = re.compile(r'(<)|(>)')
no_tags = [find.sub('', t) for t in lst]
print(no_tags)
print(no_tags[0])
valid_html(test_strings)
My output is:
valid_html(test_strings)
['z', 'x', 'c', '/v', '/b', '/n']
z
['paa', 'ore', '/ore', 'e', '/e', '/paa']
paa
['paa', 'ore', '/lan', '/ore', '/paa']
paa
['paa', 'ore', '/ore', '/paa', '/paa']
paa
['paa', 'ore', '/paa', '/ore']
paa
Thank you for your time!
You are inserting inside the loop and printing inside the loop. You need to print outside the for loop of need to return the same
def valid_html(list_of_strings):
matches = [[s] for s in list_of_strings]
lst = []
l=[]
for item in matches:
tagsRegex = re.compile(r'(<.{0,3}>|</.{0,3}>)')
lst = (tagsRegex.findall(str(item)))
find = re.compile(r'(<)|(>)')
no_tags = [find.sub('', t) for t in lst]
l.append(no_tags)
return l
valid_html(list_of_strings)[0]
Usually I would use a comprehension to change my list of lists to a list. However, I don't want to lose the empty lists as I will zip the final list to another list and I need to maintain the placings.
I have something like
list_of_lists = [['a'],['b'],[],['c'],[],[],['d']] and I use this
[x for sublist in list_of_lists for x in sublist]
which gives me
['a','b','c','d']
but what I would like is
['a','b','','c','','','d']
Sorry if this is a stupid question, I am new to python.
Thanks for any help!
Are you starting with the strings 'a', 'b', etc.? If so then you can use ''.join to convert ['a'] into 'a' and [] into ''.
[''.join(l) for l in list_of_lists]
Simply choose [''] instead of the empty list when presented with an empty sublist:
list_of_lists = [['a'],['b'], [], ['c'], [], [], ['d']]
[x for sublist in list_of_lists for x in sublist or ['']]
If you have some more complicated criteria for treating some sublists specially, you can use ... if ... else ...:
[x for sublist in list_of_lists for x in (sublist if len(sublist)%2==1 else [42])]
P.s. I'm assumig that the lack of quotes in the original is an oversight.
Something like:
a = b = c = d = 3
lol = [[a],[b],[],[c],[],[],[d]]
from itertools import chain
print list(chain.from_iterable(el or [[]] for el in lol))
# [3, 3, [], 3, [], [], 3]
>>> result = []
>>> for l in list_of_lists:
if len(l) >0:
result += l
else:
result.append('')
>>> result
['a', 'b', '', 'c', '', '', 'd']