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.
Related
I am trying to figure out how to parse a list into a list of lists.
tileElements = browser.find_element(By.CLASS_NAME, 'tile-container')
tileHTML = (str(tileElements.get_attribute('innerHTML')))
tileNUMS = re.findall('\d+',tileHTML)
NumTiles = int(len(tileNUMS)/4)
#parse out list, each 4 list items are one tile
print(str(tileNUMS))
print(str(NumTiles))
TileList = [[i+j for i in range(len(tileNUMS))]for j in range (NumTiles)]
print(str(TileList))
The first part of this code works find and gives me a list of Tile Numbers:
['2', '3', '1', '2', '2', '4', '4', '2']
However, what I need is a list of lists made out of this and that is where I am getting stuck.
The list of lists should be 4 elements long and look like this:
[['2', '3', '1', '2'] , ['2', '4', '4', '2']]
It should be able to do this for as many tiles as there are in the game (up to 19 I believe). It would be really nice if when the middle numbers are repeated that the two outside numbers are replaced with the latest value from the source list.
You can use a list comprehension to get slices from the list like so.
elements = ['2', '3', '1', '2', '2', '4', '4', '2']
size = 4
result = [elements[i:i+size] for i in range(0, len(elements), size)]
(By the way, there's no need to cast things into str to print them, and tileHTML is probably already a string, too.)
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']
I want to generate a nested 2 level list from the input numbers. The end of the line is 'enter'.
a = [[i for i in input().split()] for i in input().split (sep = '\ n')]
In this case, this takes only the second line.
For example:
1 2 3
4 5 6
7 8 9
It will output like this:
[['4', '5', '6']]
I want to get the final result like this:
[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]
Help find a mistake. Thanks.
One way to do it would be:
[x.split() for x in data.splitlines()]
Or if you want the items to be an int:
[[int(x) for x in x.split()] for x in data.splitlines()]
Code:
a = [[j for j in i.split()] for i in input().split(sep = '\n')]
You want the inside list to enumerate over the elements of the outside list.
Besides, remove the extra spaces.
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)]
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']]