List: [['1', '2', '4'],['1', '4', '8'],['03', '8', '6', '1', '62', '7'],['53', '8', '2', '82']]
below code on list :
neighbor1 = [list[i:i + 2] for i in range(0, len(list), 1)]
output:
[[['1', '2', '4'],['1', '4', '8']],[['03', '8', '6', '1', '62', '7'],['53', '8', '2', '82']]]
[[['1', '2', '4'],['1', '4', '8']],[['03', '8', '6', '1', '62', '7'],['53', '8', '2', '82']]]
but i want :
[[['1','2'],['2','4']],[['1','4'],['4','8']],[['03','8'],['8','6'],['6','1'],['1','62'],['62','7']],[['53','8'],['8','2'],['2','82']]]
You were almost there, you just need to go one level deeper:
[[x[i:i+2] for i in range(len(x)-1)] for x in List]
btw never use keyword list as variable name, or you can run into some really weird things...
You need to group elements by pairs.
A classic way for that is:
for p, n in zip(your_list[:-1], your_list[1:]):
pair = p, n
Where p represents each previous element and n represents each next.
With that in hand, you’ll manage to solve your problem.
For instance:
rows = [['1', '2', '4'],
['1', '4', '8'],
['03', '8', '6', '1', '62', '7'],
['53', '8', '2', '82']]
result = [list(zip(row[:-1], row[1:]))
for row in rows]
print(result)
You get:
[[('1', '2'), ('2', '4')], [('1', '4'), ('4', '8')], [('03', '8'), ('8', '6'), ('6', '1'), ('1', '62'), ('62', '7')], [('53', '8'), ('8', '2'), ('2', '82')]]
Related
I am pretty new to python and am trying to learn how to manipulate lists. This is stumping me and I am sure it is very easy to do without a hundred lines of code with if statements which is the only way I can think to do it.
Setup:
tileNUMS = ['4', '2', '4', '4', '2', '3', '4', '2', '2', '4', '1', '2', '2', '4', '3', '2', '2', '4', '3', '2', '4', '4', '3', '4', '4', '4', '4', '4']
TileList = [tileNUMS[i:i+4] for i in range (0, len(tileNUMS),4)]
Returns:
[['4', '2', '4', '4'], ['2', '3', '4', '2'], ['2', '4', '1', '2'], ['2', '4', '3', '2'], ['2', '4', '3', '2'], ['4', '4', '3', '4'], ['4', '4', '4', '4']]
The two outside numbers are values, and the two inside numbers are position.
What I would like is if the middle two values are repeated i.e. '4', '3' above, then only the last value of that repetition gets added to the list.
i.e.
[['4', '2', '4', '4'], ['2', '3', '4', '2'], ['2', '4', '1', '2'], ['4', '4', '3', '4'], ['4', '4', '4', '4']]
After cleaning repeated positions, I want to end up with a list with every position (middle two numbers) from '1', '1' to '4', '4' and the value of that tile as the third item in the list, including 0 as a value if it is not present in the original list.
i.e.
[['1', '1', 0], ['1', '2', 0], ['1', '3', 0], ['1', '4', 0], ['2', '1', 0], ... ['4', '4', '4']
I hope this makes sense. Thank you!!
Now that's a unique list manipulation..
Does every "tile" (4 elements list) always has first and last same elements?
Let's assume it does so I will treat each tile as a 3 elements list.
I took the liberty to change some more stuff, like using ints , not str to save your data.
I'd recommend dictionaries.
This should put you in a good start:
tile_nums = ['4', '2', '4', '4', '2', '3', '4', '2', '2', '4', '1', '2', '2', '4', '3', '2', '2', '4', '3', '2', '4', '4', '3', '4', '4', '4', '4', '4']
ROW_INDEX_POSITION = 1
COL_INDEX_POSITION = 2
VALUE_POSITION = 0
BATCH_LEN = 4
tile_list = [tile_nums[i: i + BATCH_LEN] for i in range (0, len(tile_nums), BATCH_LEN)]
# dict would allow us to keep a UNIQUED collection which saves the latests values.
only_latest_indexes = dict(((int(tile[ROW_INDEX_POSITION]), int(tile[COL_INDEX_POSITION])), int(tile[VALUE_POSITION])) for tile in tile_list)
result = {}
for i in range(1, BATCH_LEN + 1):
for j in range(1, BATCH_LEN + 1):
result[(i, j)] = only_latest_indexes.get((i, j), 0)
print(result)
To just remove duplicates:
>>> set(tuple(x) for x in tile_nums)
{('2', '3', '4', '2'), ('4', '4', '3', '4'), ('4', '2', '4', '4'), ('2', '4', '1', '2'), ('2', '4', '3', '2'), ('4', '4', '4', '4')}
I'd change the values to int types instead of str types, and use tuple objects instead of list objects to hold them, like so:
>>> x = [tuple(int(i)for i in x) for x in tile_nums]
>>> x
[(4, 2, 4, 4), (2, 3, 4, 2), (2, 4, 1, 2), (2, 4, 3, 2), (2, 4, 3, 2), (4, 4, 3, 4), (4, 4, 4, 4)]
if you need to use the numbers as strings later, just convert them.
n=10
fun=list(map(lambda x:[j for j in range(x)],n))
print(fun)
expected output is:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# using map (map works on an iterable)
n=10
fun=lambda x: (range(x)) # remember this is a function (so call it)
fun=list(map(str, fun(n)))
print(fun)
# directly
n=10
fun=list(map(str, (range(n))))
print(fun)
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
Python docs for reference:
map(): https://docs.python.org/3/library/functions.html#map
range(): https://docs.python.org/3/library/functions.html#func-range
lambda(): https://docs.python.org/3/library/ast.html?highlight=lambda#ast.Lambda
This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 6 years ago.
I have two nested for loops and two lists, I want one of tle list to re-initialize after one iteration of inner loop.
def test():
i = ['1','5','9','3','6','4']
for x in xrange(0,len(i)):
j = ['6', '7', '9', '3']
newi = i
for y in xrange(0,len(j)):
newi[x] = j[y]
print "i", i
print "end of one iteration on finner loop"
print "newi", newi
test()
Its a dummy code, I want a clean new instance of newi to be that of i after one iteration of inner loop, currently it preserver the value of inner loop
current output:
i ['6', '5', '9', '3', '6', '4']
i ['7', '5', '9', '3', '6', '4']
i ['9', '5', '9', '3', '6', '4']
i ['3', '5', '9', '3', '6', '4']
end of one iteration on inner loop
newi ['3', '5', '9', '3', '6', '4']
i ['3', '6', '9', '3', '6', '4']
i ['3', '7', '9', '3', '6', '4']
i ['3', '9', '9', '3', '6', '4']
i ['3', '3', '9', '3', '6', '4']
end of one iteration on inner loop
newi ['3', '3', '9', '3', '6', '4']
i ['3', '3', '6', '3', '6', '4']
i ['3', '3', '7', '3', '6', '4']
i ['3', '3', '9', '3', '6', '4']
i ['3', '3', '3', '3', '6', '4']
end of one iteration on inner loop
newi ['3', '3', '3', '3', '6', '4']
i ['3', '3', '3', '6', '6', '4']
i ['3', '3', '3', '7', '6', '4']
i ['3', '3', '3', '9', '6', '4']
i ['3', '3', '3', '3', '6', '4']
end of one iteration on inner loop
newi ['3', '3', '3', '3', '6', '4']
i ['3', '3', '3', '3', '6', '4']
i ['3', '3', '3', '3', '7', '4']
i ['3', '3', '3', '3', '9', '4']
i ['3', '3', '3', '3', '3', '4']
end of one iteration on inner loop
newi ['3', '3', '3', '3', '3', '4']
i ['3', '3', '3', '3', '3', '6']
i ['3', '3', '3', '3', '3', '7']
i ['3', '3', '3', '3', '3', '9']
i ['3', '3', '3', '3', '3', '3']
end of one iteration on inner loop
newi ['3', '3', '3', '3', '3', '3']
Instead of:
newi = i
replace with:
newi = list(i) # list(i) creates another copy i
I know that you can swap 2 single indexes in Python
r = ['1', '2', '3', '4', '5', '6', '7', '8']
r[2], r[4] = r[4], r[2]
output:
['1', '2', '5', '4', '3', '6', '7', '8']
But why can't you swap 2 slices of indexes in python?
r = ['1', '2', '3', '4', '5', '6', '7', '8']
I want to swap the numbers 3 + 4 with 5 + 6 + 7 in r:
r[2:4], r[4:7] = r[4:7], r[2:4]
output:
['1', '2', '5', '6', '3', '4', '7', '8']
expected output:
['1', '2', '5', '6', '7', '3', '4', '8']
What did I wrong?
output:
The slicing is working as it should. You are replacing slices of different lengths. r[2:4] is two items, and r[4:7] is three items.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:4]
['3', '4']
>>> r[4:7]
['5', '6', '7']
So when ['3', '4'] is replaced, it can only fit ['5', '6'], and when ['5', '6', '7'] is replaced, it only gets ['3', '4']. So you have ['1', '2',, then the next two elements are the first two elements from ['5', '6', '7'] which is just ['5', '6', then the two elements from ['3', '4' go next, then the remaining '7', '8'].
If you want to replace the slices, you have to start slices at the right places and allocate an appropriate size in the array for each slice:
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
old index: 4 5 6 2 3
new index: 2 3 4 5 6
Think of this:
r[2:4], r[4:7] = r[4:7], r[2:4]
as similar to this:
original_r = list(r)
r[2:4] = original_r[4:7]
r[4:7] = original_r[2:4]
So, by the time it gets to the third line of that, the 4th element isn't what you think it is anymore... You replaced '3', '4' with '5', '6', '7', and now the [4:7] slice starts with that '7'.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
In your code:
>>> r[2:4], r[4:7] = r[4:7], r[2:4]
You are assigning r[4:7] which have 3 elements to r[2:4] which have only 2.
In the code I posted:
>>> >>> r[2:5], r[5:7] = r[4:7], r[2:4]
r[4:7] which is ['5', '6', '7'], replaces
r[2:5] which is ['3', '4', '5']
r resulting in ['1', '2', '5', '6', '7', '6', '7', '8']
and then:
r[2:4] which was ['3', '4'], replaces
r[5:7] which is ['6', '7']
So final result being:
['1', '2', '5', '6', '7', '3', '4', '8']
Given string is '0123456789'.
I wanted to generate its one millionth permutation(1000000).
I wanted to give itertools.permutations a first try:
In [85]: import itertools
In [86]: a = list(itertools.permutations('0123456789'))
In [87]: a[1]
Out[87]: ('0', '1', '2', '3', '4', '5', '6', '7', '9', '8')
In [88]: a[1000000]
Out[88]: ('2', '7', '8', '3', '9', '1', '5', '6', '0', '4')
However if i run the following code:
def perm(S, perms=[], current=[], maximum=None):
if maximum and len(perms) > maximum:
return
size = len(S)
for i in range(size):
subset = list(S)
del(subset[i])
tmp_current = list(current)
tmp_current.append(S[i])
if size > 1:
perm(subset, perms, tmp_current, maximum)
else:
perms.append(tmp_current)
if maximum:
if len(perms) == maximum:
print tmp_current
return
perm('0123456789', maximum=1000000)
# the result is ['2', '7', '8', '3', '9', '1', '5', '4', '6', '0']
The answer from itertools.permutations and from the above psuedo code does not match.
[2783915604] from itertools
[2783915460] from the snippet above
The second answer is the correct answer. Could anyone please explain me why the first process is not yielding a correct result?
You messed up with indexes:
>>> a[999999]
('2', '7', '8', '3', '9', '1', '5', '4', '6', '0')
You code quits when generates 1m result. And 1m element in a list has index 999999.