This question already has answers here:
How do I split a list into equally-sized chunks?
(66 answers)
Closed 5 years ago.
I frequently run into a problem where I'm trying to make a list of lists of a certain length from a string.
This is an example where I have a string, but would like to make a list of lists of length 3:
x = '123456789'
target_length = 3
new = [i for i in x]
final = [new[i:i+target_length] for i in range(0, len(x), target_length)]
print(final)
Output:
[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
So, this works, but feels so clunky.
Is there a better way to combine these arguments into one line or do you think that would make the code unreadable?
If you want to do it in one line you can just create the lists inside your comprehension:
x = '123456789'
target_length = 3
[list(x[i:i+target_length]) for i in range(0, len(x), target_length)]
>> [['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
This does it in one line:
f2 = [[x[(j * target_length) + i] for i in range(target_length)] for j in range(target_length)]
Related
This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 6 months ago.
I am trying to replace elements in a 2d list. e-g I have this list
[['0', '0', '0'],
['0', '0', '0'],
['0', '0', '0']]
and I want to convert first row to 1,1,1
here is what I have tried
l = [["0"]*3]*3
for i in range(3):
l[0][i] = "1"
but I am getting the following output instead
[['1', '1', '1'],
['1', '1', '1'],
['1', '1', '1']]
why is it converting all the rows to 1s?
I also tried to insert one element like this
l[1][1] = 1
and this coverts the [1] element of every row to 1 like this
[['0', 1, '0'],
['0', 1, '0'],
['0', 1, '0']]
Am I making a silly mistake or my interpreter has issues?
Because of the multiplication, the inner lists are all the same object. This is basically the same as:
inner = ["0"] * 3
outer = [inner, inner, inner]
When you now change inner, (or one element of outer), you change all references of it.
If you want to generate a 2D list with independent elements, i suggest list comprehension:
[["0" for i in range(3)] for j in range (3)]
Your interpreter is not the issue. I think you are just constructing your matrix incorrectly. You can just change the first row of the matrix as such
matrix = [['0'] * 3 for _ in range(3)
for i in range(3):
matrix[0][i] = '1'
Use
l = [ [0]*3 for i in range(3)]
In your code they all point to the same object.
This question already has answers here:
How to sort python list of strings of numbers
(4 answers)
Closed 2 years ago.
I tried to sort a list of string that are actually integers but i do not get the right sort value. How do i sort it in a way that it is sorted according to the integer value of string ?
a = ['10', '1', '3', '2', '5', '4']
print(sorted(a))
Output:
['1', '10', '2', '3', '4', '5']
Output wanted:
['1', '2', '3', '4', '5', '10']
We have to use the lambda as a key and make each string to int before the sorted function happens.
sorted(a,key=lambda i: int(i))
Output :
['1', '2', '3', '4', '5', '10']
More shorter way -> sorted(a,key=int). Thanks to #Mark for commenting.
So one of the ways to approach this problem is converting the list to a list integers by iterating through each element and converting them to integers and later sort it and again converting it to a list of strings again.
You could convert the strings to integers, sort them, and then convert back to strings. Example using list comprehensions:
sorted_a = [str(x) for x in sorted(int(y) for y in a)]
More verbose version:
int_a = [int(x) for x in a] # Convert all elements of a to ints
sorted_int_a = sorted(int_a) # Sort the int list
sorted_str_a = [str(x) for x in sorted_int_a] # Convert all elements of int list to str
print(sorted_str_a)
Note: #tedd's solution to this problem is the preferred solution to this problem, I would definitely recommend that over this.
Whenever you have a list of elements and you want to sort using some property of the elements, use key argument (see the docs).
Here's what it looks like:
>>> a = ['10', '1', '3', '2', '5', '4']
>>> print(sorted(a))
['1', '10', '2', '3', '4', '5']
>>> print(sorted(a, key=lambda el: int(el)))
['1', '2', '3', '4', '5', '10']
This question already has an answer here:
How to join mixed list (array) (with integers in it) in Python?
(1 answer)
Closed 3 years ago.
I have the list below, which contains strings and integers. How do I make a string of them? Tried to use
''.join(l)
but it does't work, because there are integers on the list(specifically, L[1] is an integer, and the others are all strings.). Can you help?
L=['1', 9, ':', '0', '5', ':', '4', '5']
#expected "19:05:45"
You can convert each number in the list into a string with a for loop or list comprehension. Like so:
l = ['1', 9, ':', '0', '5', ':', '4', '5']
''.join([str(x) for x in l])
'19:05:45'
Generators are perfect in this case:
>>> l = ['1', 9, ':', '0', '5', ':', '4', '5']
>>> ''.join(str(x) for x in l)
'19:05:45'
This looks the same as a list comprehension but does not require the creation of another list instance.
Just map all the elements to string before joining.
>>> ''.join(map(str,['1', 9, ':', '0', '5', ':', '4', '5']))
'19:05:45'
You can do it in a for loop
list_str = ''
for i in l:
list_str += str(i)
Or a with a list comprehension
list_str = ''.join([str(i) for i in l])
This question already has answers here:
Split a list into parts based on a set of indexes in Python
(9 answers)
Closed 6 years ago.
I have a list of strings - foo and another list of integers- bar which keeps the track of important indices in foo.
For example:
foo = [{}.format(i) for i in range(1, 11)] # not necessarily of this format
bar = [0, 3, 5]
I would like to create a recipe for creating a list of lists, each list obtained by splitting foo based on indices in bar.
Expected output for the above example:
[['1', '2', '3'], ['4', '5'], ['6', '7', '8', '9', '10']]
For achieving this, I have created the following function which works fine:
result = []
for index, value in enumerate(b):
if index == len(b) - 1:
result.append(a[value:])
elif index == 0 and value != 0:
result.append(a[0: value])
else:
result.append(a[value: b[index + 1]])
However, I find this code highly Non-Pythonic, thanks to my C-Java background.
I would like to know a better solution to this problem (maybe we can use itertools somehow).
You could do as follows:
In [3]: [foo[a:b] for a, b in zip(bar, bar[1:]+[None])]
Out[3]: [['1', '2', '3'], ['4', '5'], ['6', '7', '8', '9', '10']]
Here is one way using a list comprehension:
In [107]: bar = bar + [len(foo)] if bar[-1] < len(foo) else bar
In [110]: [foo[i:j] for i, j in zip(bar, bar[1:])]
Out[110]: [['1', '2', '3'], ['4', '5'], ['6', '7', '8', '9', '10']]
This question already has answers here:
How do I make a flat list out of a list of lists?
(34 answers)
Closed 6 years ago.
I am trying to find a short and elegant way in order to access all individual elements in nested lists. For example:
lst1 = ['1', '2', '3']
lst2 = ['4', '5']
outer = [lst1, lst2]
Is there a list comprehension that would return ['1', '2', '3', '4', '5']?
There are two short similar ways to do it:
import itertools
# with unpacking
list(itertools.chain(*outer))
# without unpacking
list(itertools.chain.from_iterable(outer))
import itertools
lst1 = ['1', '2', '3']
lst2 = ['4', '5']
outer = [lst1, lst2]
flattened = list(itertools.chain(*outer))
['1', '2', '3', '4', '5']