When I write this code:
f=['a','b','c',['d','e','f']]
def j(f):
p=f[:]
for i in range(len(f)):
if type(p[i]) == list:
p[i].reverse()
p.reverse()
return p
print(j(f), f)
I expect that the result would be:
[['f', 'e', 'd'], 'c', 'b', 'a'] ['a', 'b', 'c', ['d', 'e', 'f']]
But the result I see is:
[['f', 'e', 'd'], 'c', 'b', 'a'] ['a', 'b', 'c', ['f', 'e', 'd']]
Why? And how can I write a code that do what I expect?
reverse modifies the list in place, you actually want to create a new list, so you don't reverse the one you've got, something like this:
def j(f):
p=f[:]
for i in range(len(f)):
if type(p[i]) == list:
p[i] = p[i][::-1]
p.reverse()
return p
Related
Why is the longest_palindrome variable updated when the isPalindrome() function evaluates to False? The if/else condition is not behaving as I would expect.
def palindromeCutting(s):
if s == "":
return ""
letters = list(s)
while len(letters) > 0:
tmp = []
longest_palindrome = []
for i in range(len(letters)):
tmp.append(letters[i])
if isPalindrome(tmp):
print("updating longest with tmp")
longest_palindrome = tmp
print("longest_palindrome:",longest_palindrome)
if len(longest_palindrome) > 1:
l = len(longest_palindrome)
letters = letters[l:]
else:
return "".join(letters)
def isPalindrome(arr):
left, right = 0, len(arr) - 1
while left <= right:
if arr[left] != arr[right]:
return False
left += 1
right -= 1
return True
The output for this when run with s = "aaacodedoc" is:
longest_palindrome: ['a']
longest_palindrome: ['a', 'a']
longest_palindrome: ['a', 'a', 'a']
longest_palindrome: ['a', 'a', 'a', 'c']
longest_palindrome: ['a', 'a', 'a', 'c', 'o']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd', 'o']
longest_palindrome: ['a', 'a', 'a', 'c', 'o', 'd', 'e', 'd', 'o', 'c']
The problem is that you are setting longest_palindrom to tmp. From that point on, tmp and longest_palindrom are pointing to the same object. Whenever tmp is modified, the modification is reflected on longest_palindrom, and vice-versa.
To avoid that, you could instead set longest_palindrom to a copy of tmp, replacing the line
longest_palindrom = tmp
by
longest_palindrom = tmp[:]
which sets longest_palindrom to a new list containing the elements of tmp.
If you want a more in-depth explanation of list aliasing, the answers to this question explain it very well.
you are referencing tmp with longest_palindrome.
So they both point to the same object.
After 3rd iteration tmp object is still growing so the longest_palindrome does also.
longest_palindrome = tmp
You can try by copying / creating new object with the same content:
longest_palindrome = tmp[:]
If I have the following list of lists for example:
[['A', 'B', 'C'], ['A', 'D', 'E', 'B', 'C']]
How could I get a List with lists of only 3 elems each (in case they are greater than 3 elems), if they have not more than 3 elems we don't need to do nothing, we just need to separate the elems with more than 3 like the following:
[['A', 'B', 'C'], ['A', 'D', 'E'], ['D', 'E', 'B'], ['E', 'B', 'C']]
Could you help me with this ? I've been trying for a long time without success, kinda new to Python.
Edit:
Well, I resolved this in this way:
def separate_in_three(lista):
paths = []
for path in lista:
if len(path) <= 3:
paths.append(path)
else:
for node in range(len(path)-1):
paths.append(path[:3])
path.pop(0);
if(len(path) == 3):
paths.append(path)
break
return paths
Seems to resolve my problem, I could use the list in comprehension, were it would be much more efficient than the way I did ?
Thanks for the help btw !
you can use list comprehension like below.
l = [['A', 'B', 'C'], ['A', 'D', 'E', 'B', 'C','Z']]
[l[0]] + [l[1][i: i+len(l[0])] for i in range(1 + len(l[1]) - len(l[0]))]
I am trying to find a slice, of variable size, in a list and replace it with one element:
ls = ['c', 'b', 'c', 'd', 'c']
lt = ['b', 'c']
r = 'bc'
for s,next_s in zip(ls, ls[1:]):
for t, next_t in zip(lt, lt[1:]):
if (s, next_s) == (t, next_t):
i = ls.index(s)
ii = ls.index(next_s)
del ls[i]
del ls[ii]
ls.insert(i, r)
print (ls)
This works only sometimes, producing:
['c', 'bc', 'd', 'c']
but if lt = ['d', 'c'] and r = 'dc', it fails producing:
['b', 'c', 'c', 'dc']
How to fix that? Or what is a better way to handle this?
Simple way that might work for you (depends on whether lt can appear multiple times and on what to do then).
ls = ['c', 'b', 'c', 'd', 'c']
lt = ['b', 'c']
r = 'bc'
for i in range(len(ls)):
if ls[i:i+len(lt)] == lt:
ls[i:i+len(lt)] = [r]
print(ls)
I have a list of some characters. When I print it I get the following output:
['a', 'b', 'c', 'd', 'e']
But what I want is this:
['a',
'b',
'c',
'd',
'e']
I have tried .join but that removes the [] and the '' and I dont want that.
Any help appreciated. I have tried to search but I can only find .join solutions.
Thanks
Edit: is it possible to return the list this way also? or just print it like that?
Here's an hackish way to do it with print in Python 3:
>>> print(*str(lst).split(','), sep=',\n')
['a',
'b',
'c',
'd',
'e']
You can use the pprint ("pretty-print") module:
from pprint import pprint
pprint(['a', 'b', 'c', 'd', 'e'], width=1)
If you want to get the value as a string instead of printing it, use pformat instead of pprint.
Simple str.replace() approach:
lst = ['a', 'b', 'c', 'd', 'e']
print(repr(lst).replace(',', ',\n'))
The output:
['a',
'b',
'c',
'd',
'e']
Another possible way:
>>> ok = ['a', 'b', 'c', 'd', 'e']
>>> for x in ok.__repr__().split():
>>> print(x)
...
...
['a',
'b',
'c',
'd',
'e']
# py2
# for x in ok.__str__().split():print(x)
I started with something like this:
[a,b,s,d]
[k,e,f,s,d]
[o,w,g]
Then I wanted to rearrange them by length in descending order so that I get this:
[k,e,f,s,d]
[a,b,s,d]
[o,w,g]
However, to do that, I appended each of those into an array as such:
arr = [[a,b,s,d], [k,e,f,s,d], [o,w,g]]
so that I could just use:
sorted(arr, key=len).reverse()
But now I can't unpack arr to just get:
[k,e,f,s,d]
[a,b,s,d]
[o,w,g]
Ideas?
Thanks.
reverse() is an in-place function:
arr = [['a','b','s','d'], ['k','e','f','s','d'], ['o','w','g']]
a = sorted(arr, key=len)
print a
# [['o', 'w', 'g'], ['a', 'b', 's', 'd'], ['k', 'e', 'f', 's', 'd']]
print a.reverse()
# None
print a
# [['k', 'e', 'f', 's', 'd'], ['a', 'b', 's', 'd'], ['o', 'w', 'g']]
reverse() has no output, but it does reverse the array.