Having a Python list like the following one:
list1 = [ "abc", "def", "ghi" ]
How can I obtain sub-lists for each character of the strings ?
list3 = [ ["a"], ["b"], ["c"] ]
list4 = [ ["d"], ["e"], ["f"] ]
list5 = [ ["g"], ["h"], ["i"] ]
Do not generate variables programmatically, this leads to unclear code and is often a source of bugs, use a container instead (dictionaries are ideal).
Using a dictionary comprehension:
list1 = [ "abc", "def", "ghi" ]
lists = {'list%s' % (i+3): [[e] for e in s]]
for i,s in enumerate(list1)}
output:
>>> lists
{'list3': [['a'], ['b'], ['c']],
'list4': [['d'], ['e'], ['f']],
'list5': [['g'], ['h'], ['i']]}
>>> lists['list3']
[['a'], ['b'], ['c']]
NB. you could also simply use the number as key (3/4/5)
To get a list from a string use list(string)
list('hello') # -> ['h', 'e', 'l', 'l', 'o']
And if you want to wrap the individual characters in a list do it like this:
[list(c) for c in 'hello'] # --> [['h'], ['e'], ['l'], ['l'], ['o']]
But that is useful only if you want to change the list afterward.
Note that you can index a string like so
'hello'[2] # --> 'l'
This is how to break a list then break it into character list.
list1 = ["abc", "def", "ghi"]
list3 = list(list1[0])
list4 = list(list1[1])
list5 = list(list1[2])
Related
I have a list ['a','b','c','d'], want to make another list, like this: ['a', 'ab', abc', 'abcd']?
Thanks
Tried:
list1=['a','b','c', 'd']
for i in range(1, (len(list1)+1)):
for j in range(1, 1+i):
print(*[list1[j-1]], end = "")
print()
returns:
a
ab
abc
abcd
It does print what i want, but not sure,how to add it to a list to look like ['a', 'ab', abc', 'abcd']
Use itertools.accumulate, which by default sums up the elements for accumulation like a cummulative sum. Since addition (__add__) is defined for str and results in the concatenation of the strings
assert "a" + "b" == "ab"
we can use accumulate as is:
import itertools
list1 = ["a", "b", "c", "d"]
list2 = list(itertools.accumulate(list1)) # list() because accumulate returns an iterator
print(list2) # ['a', 'ab', 'abc', 'abcd']
Append to a second list in a loop:
list1=['a','b','c', 'd']
list2 = []
s = ''
for c in list1:
s += c
list2.append(s)
print(list2)
Output:
['a', 'ab', 'abc', 'abcd']
list1=['a','b','c', 'd']
l = []
for i in range(len(list1)):
l.append("".join(list1[:i+1]))
print(l)
Printing stuff is useless if you want to do ANYTHING else with the data you are printing. Only use it when you actually want to display something to console.
You could form a string and slice it in a list comprehension:
s = ''.join(['a', 'b', 'c', 'd'])
out = [s[:i+1] for i, _ in enumerate(s)]
print(out):
['a', 'ab', 'abc', 'abcd']
You can do this in a list comprehension:
vals = ['a', 'b', 'c', 'd']
res = [''.join(vals[:i+1]) for i, _ in enumerate(vals)]
Code:
[''.join(list1[:i+1]) for i,l in enumerate(list1)]
Output:
['a', 'ab', 'abc', 'abcd']
how do I convert all the numerical strings, inside a list of list that contains both alphabetical, and numerical strings, into an integer?
My Output:
[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
Intended Output:
[[69, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420, 'F']]
Note that my code reads a CSV file. Thanks everyone
def get_csv_as_table(a, b):
s = False
import csv
with open(a) as csv_file:
file_reader = csv.reader(csv_file, delimiter=b)
member = list(file_reader)
print(member)
print ("Enter filename: ")
a = input()
print ("Enter the delimiter: ")
b = input()
get_csv_as_table(a, b)
You can use list comprehension to achieve this. The only minor downside to this is that you will be creating a new list for this instead of modifying the existing list.
my_list = [['69', 'Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
filtered_list = [
[int(item) if item.isdigit() else item for item in sub_list]
for sub_list in my_list
]
If you want to edit the list in-place, you can use traditional for-loop. The following code will edit the existing list without creating a new list. This could turn out to be useful in case you have a large list.
my_list = [['69', 'Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
for i in range(len(my_list)):
for j in range(len(my_list[i])):
if my_list[i][j].isdigit():
my_list[i][j] = int(my_list[i][j])
str.isdigit() checks if a given string is a number or not. An important note to keep in mind is that, it does not work for floating-point numbers, just integers. Once the condition passes, the item is converted to integer.
Yoy have to combine 2 levels of list-comprehension and use str.isdigit()
values = [
[int(val) if val.isdigit() else val for val in row]
for row in values
]
Try with 2-level list comprehension and int()+.isdigit() power combo in list comprehension ;-)
l=[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
l=[[int(y) if y.isdigit() else y for y in x] for x in l]
print(l)
Output:
[[69, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420, 'F']]
.isdigit() only works on string representation of pure integers, In case if you have floats too then replace '.' to nothing ;-)
l=[['69', ' Test', 'Results'], ['A', 'B', 'C'], ['D', '420', 'F']]
l=[[float(y) if y.replace('.','').isdigit() else y for y in x] for x in l]
print(l)
Output:
[[69.0, ' Test', 'Results'], ['A', 'B', 'C'], ['D', 420.0, 'F']]
how can I extract for example [['A', '123'], ['A', '456']] from mylist if I filtered by 'A'?
mylist = [['A', '123'],
['A', '456'],
['B','847'],
['B','677']]
Here are two ways to achieve the results you want.
mylist = [['A', '123'],
['A', '456'],
['B','847'],
['B','677']]
letter = 'A'
# Using list comprehension
print([l for l in mylist if l[0] == letter])
# Using filer function
print(list(filter(lambda l: l[0] == letter, mylist)))
I made a code for you.
mylist = [['A', '123'],
['A', '456'],
['B', '847'],
['B', '677']]
output = [lst for lst in mylist if 'A' in lst]
print(output)
Or you can use this code;
output = [lst for lst in mylist if 'A' == lst[0]]
If I had a list like this:
L = [
['a', 'b'],
['c', 'f'],
['d', 'e']
]
I know that I could check if e.g. 'f' was contained in any of the sub lists by using any in the following way:
if any('f' in sublist for sublist in L) # True
But how would I go about searching through second sub lists, i.e. if the list was initialized the following way:
L = [
[
['a', 'b'],
['c', 'f'],
['d', 'e']
],
[
['z', 'i', 'l'],
['k']
]
]
I tried chaining the for in expressions like this:
if any('f' in second_sublist for second_sublist in sublist for sublist in L)
However, this crashes because name 'sublist' is not defined.
First write your logic as a regular for loop:
for first_sub in L:
for second_sub in first_sub:
if 'f' in second_sub:
print('Match!')
break
Then rewrite as a generator expression with the for statements in the same order:
any('f' in second_sub for first_sub in L for second_sub in first_sub)
If you don't need to know where 'f' is located you can leverage itertools here as well.
import itertools
any('f' in x for x in itertools.chain.from_iterable(l))
This will flatten your nested lists and evaluate each list separately. The benefit here is if you have three nested lists this solution would still function without having to continue writing nest for loops.
for a given list for example:
[
'A',
[
'B',
['D','C'],
['C','D']
],
['C','D'],
['E','F'],
['F','E'],
[
['not','M'],
'N',
['not','M']
]
]
I want to remove the duplicate element in it, the result of the above list should be:
[
'A',
[
'B',
['C','D']
],
['C','D'],
['E','F'],
[
['not','M'],
'N'
]
]
It has two rules: ['not','A'] represents ~A, and it can be seen as one element.
If the value is same but order not, we consider it the same.So ['C','D'] is same as ['D','C']
Can anyone one help me write this function in python to realize the requirement?
In general, I agree with Klaus D.'s comment. But I thought the question was interesting since the easiest way I could think of was using lists->tuples->sets and that gets kind of interesting when you want to remove elements. It also causes you to lose the ordering of the original input list (As noted by Adam Smith).
So given all that, consider:
import itertools
def _reduce(lst):
if not isinstance(lst, list): return lst
seen = []
for x in lst:
if not any(list(perm) in seen for perm in itertools.permutations(x)):
seen.append(_reduce(x))
return seen
Which you can run by:
lst = [
'A',
[
'B',
['D','C'],
['C','D']
],
['C','D'],
['E','F'],
['F','E'],
[
['not','M'],
'N',
['not','M']
]
]
print _reduce(lst)
Which outputs:
[
'A',
[
'B',
['D', 'C']
],
['C', 'D'],
['E', 'F'],
[
['not', 'M'],
'N'
]
]
Note that this preserves input ordering of list elements. Also note, that because of this, this output differs slightly from your expected output (['D', 'C'] is preserved and ['C', 'D'] is discarded).
Edit Per your commment, itertools.permutations() won't suffice, since you seem to want some recursive function that will consider the permutations of the subelements as well. What about:
import itertools
def _permutations(x):
if not isinstance(x, list): return x
perms = []
for prod in itertools.product(*[_permutations(elem) for elem in x]):
for perm in itertools.permutations(prod):
perms.append(list(perm))
return perms
def _reduce(lst):
if not isinstance(lst, list): return lst
seen = []
for x in lst:
if not any(list(perm) in seen for perm in _permutations(x)):
seen.append(_reduce(x))
return seen
def lexsort(x): return sorted(str(e) for e in _permutations(x))
arrs = [
['B',['C','D']],
[['D','C'],'B'],
]
print _reduce(arrs)
Outputs:
[['B', ['C', 'D']]]