Related
This permutation comes from Udacity and is made with Python.
But i have problems to understand what does it means +1 in this line for j in range(0, len(p) + 1):. Someone could help me to understand it? I'm little bit confused.
Thanks to all!
import copy
def permute(l):
perm = []
if len(l) == 0:
perm.append([])
else:
first_element = l[0]
after_first = slice(1, None)
sub_permutes = permute(l[after_first])
for p in sub_permutes:
for j in range(0, len(p) + 1):
r = copy.deepcopy(p)
r.insert(j, first_element)
perm.append(r)
return perm
The idea behind this loop is to create a lists each with first_element in different place.
To insert an element after the last index (mimic append behavior), you would write l.insert(len(l), element)). So when they are trying to insert the first element in each place of the list they want the range to be from 0 to len(p) and be inclusive, so they add +1 to the range.
In [1]: l = [1,2,3]
In [2]: for i in range(0, len(l)+1):
...: new_l = list(l)
...: new_l.insert(i, 4)
...: print(new_l)
...:
[4, 1, 2, 3]
[1, 4, 2, 3]
[1, 2, 4, 3]
[1, 2, 3, 4] # without the +1 this line would not be created
I am using python 3.6.This program should store the value of indexes of the numbers of one array into another (index starting with 1) For Eg if array is [2,3,1] the next one should be [3,1,2].. but while implemending the list gets changed.
I tried to do with respect to values of 1st array but no use it gets changed when doing the logic.
n = int(input())
arr = input()
l = list(map(int,arr.split(' ')))
arr1= l
print(l)
for i in range(0,n):
print(l[i])
arr1[l[i]-1]=i+1
print(arr1)
Answer should be [4,1,2,3] but answer is [2,1,4,3]
enter code here
You are asking for an array of the indexes of the numbers, but your example shows the indexes +1. It would probably be cleaner to stick with zero indexing.
Nevertheless, if you're looking for a (somewhat) flexible approach, you could do something like this with a list comprehension:
>>> l = [2, 3, 1]
>>> [l.index(i+1) +1 if i+1 in l else None for i in range(max(l))]
[3, 1, 2]
Given an array that's spread out, it will fill with None:
>>> l = [2, 3, 7, 1]
>>> [l.index(i+1) +1 if i+1 in l else None for i in range(max(l))]
[4, 1, 2, None, None, None, 3]
It will silently ignore dupes:
>>> l = [2, 2, 1, 2]
>>> [l.index(i+1) +1 if i+1 in l else None for i in range(max(l))]
[3, 1]
you can do it this way:
x = [2, 3, 1]
ind = [x.index(e) for e in sorted(x)]
# if you want your indices to start from 1
[e+1 for e in ind]
I understand this question has been asked before but I haven't seen any that answer it in a way without splitting the list.
say I have a list:
num = [1,2,3,4,5,6]
I want to create a function:
rotate(lst, x):
So that if I call rotate(num, 3) it will globally edit the list num. That way when I later call print(num) it will result in [4,5,6,1,2,3].
I understand that I could write the function something like:
rotate(lst, x):
return [lst[-x:] + lst[:-x]
But I need to do this function without a return statement, and without splitting the list. What I'm thinking would work would be to put the last value of the list into a variable: q = lst[-1] and then from there create a loop that runs x amount of times that continues to move the values towards the end of the list and replacing the 0th position with whatever is stored in q.
One more thing. If I call rotate(lst, -3) then instead of rotating to the "right" it would have to rotate to the "left".
I'm new to python and having trouble wrapping my mind around this concept of manipulating lists. Thank you everyone for your time and effort. I hope this problem was clear enough.
You can use slicing assignment to modify your current strategy to do what you want. You're already generating the rotated list correctly, just modify the list in place with lst[:] = ...
def rotate(lst, x):
lst[:] = lst[-x:] + lst[:-x]
Example in the interactive interpreter:
>>> l = [1, 2, 3, 4, 5, 6]
>>> def rotate(lst, x):
... lst[:] = lst[-x:] + lst[:-x]
...
>>> rotate(l, 2)
>>> l
[5, 6, 1, 2, 3, 4]
Now rotate it backwards:
>>> rotate(l, -2)
>>> l
[1, 2, 3, 4, 5, 6]
>>> rotate(l, -2)
>>> l
[3, 4, 5, 6, 1, 2]
See this answer on a different question: https://stackoverflow.com/a/10623383/3022310
Here is a solution using a double-ended queue.
As required, it modifies the list in place, neither uses return nor uses chunks of the list.
from collections import deque
def rotate(lst, x):
d = deque(lst)
d.rotate(x)
lst[:] = d
num = [1,2,3,4,5,6]
rotate(num,3)
print(num)
rotate(num,-3)
print(num)
produces
[4, 5, 6, 1, 2, 3]
[1, 2, 3, 4, 5, 6]
Please have a look at PMOTW's tutorial on deque
def rotate(lst, num):
copy = list(lst)
for (i, val) in enumerate(lst):
lst[i] = copy[i - num]
Try:
num = [1,2,3,4,5,6]
def rotate(lst,x):
copy = list(lst)
for i in range(len(lst)):
if x<0:
lst[i+x] = copy[i]
else:
lst[i] = copy[i-x]
rotate(num, 2)
print num
Here is a simple method using pop and insert on the list.
num = [1,2,3,4,5,6]
def rotate(lst, x):
if x >= 0:
for i in range(x):
lastNum = lst.pop(-1)
lst.insert(0, lastNum)
else:
for i in range(abs(x)):
firstNum = lst.pop(0)
lst.append(firstNum)
return
print num #[1, 2, 3, 4, 5, 6]
rotate(num, 2)
print num #[5, 6, 1, 2, 3, 4]
rotate(num, -2)
print num #[1, 2, 3, 4, 5, 6]
I believe this satisfies all requirements. The idea is from the Programming Pearls book(http://goo.gl/48yJPw). To rotate a list we can reverse it and then reverse sublists with the rotating index as pivot.
def rotate(num, rot):
if rot < 0:
rot = len(num) + rot
rot = rot - 1
num.reverse()
for i in range(rot/2 + 1):
num[i], num[rot-i] = num[rot-i], num[i]
for i in range(1, (len(num) - rot)/2):
num[rot+ i], num[len(num) - i] = num[len(num) - i], num[rot+ i]
#Testing...
num = range(1, 10)
rot = -1
print num
rotate(num, rot)
print num
So I am implementing a block swap algorithm in python.
The algorithm I am following is this:
Initialize A = arr[0..d-1] and B = arr[d..n-1]
1) Do following until size of A is equal to size of B
a) If A is shorter, divide B into Bl and Br such that Br is of same
length as A. Swap A and Br to change ABlBr into BrBlA. Now A
is at its final place, so recur on pieces of B.
b) If A is longer, divide A into Al and Ar such that Al is of same
length as B Swap Al and B to change AlArB into BArAl. Now B
is at its final place, so recur on pieces of A.
2) Finally when A and B are of equal size, block swap them.
The same algorithm has been implemented in C on this website - Array Rotation
My python code for the same is
a = [1,2,3,4,5,6,7,8]
x = 2
n = len(a)
def rotate(a,x):
n = len(a)
if x == 0 or x == n:
return a
if x == n -x:
print(a)
for i in range(x):
a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
print(a)
return a
if x < n-x:
print(a)
for i in range(x):
a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
print(a)
rotate(a[:n-x],x)
else:
print(a)
for i in range(n-x):
a[i], a[(i-(n-x) + n) % n] = a[(i-(n-x) + n) % n] , a[i]
print(a)
rotate(a[n-x:], n-x)
rotate(a,x)
print(a)
I am getting the right values at each stage but the recursive function call is not returning the expected result and I cannot seem to understand the cause. Can someone explain whats wrong with my recursion ? and what can be the possible alternative.
You can rotate a list in place in Python by using a deque:
>>> from collections import deque
>>> d=deque([1,2,3,4,5])
>>> d
deque([1, 2, 3, 4, 5])
>>> d.rotate(2)
>>> d
deque([4, 5, 1, 2, 3])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5])
Or with list slices:
>>> li=[1,2,3,4,5]
>>> li[2:]+li[:2]
[3, 4, 5, 1, 2]
>>> li[-2:]+li[:-2]
[4, 5, 1, 2, 3]
Note that the sign convention is opposite with deque.rotate vs slices.
If you want a function that has the same sign convention:
def rotate(l, y=1):
if len(l) == 0:
return l
y = -y % len(l) # flip rotation direction
return l[y:] + l[:y]
>>> rotate([1,2,3,4,5],2)
[4, 5, 1, 2, 3]
>>> rotate([1,2,3,4,5],-22)
[3, 4, 5, 1, 2]
>>> rotate('abcdefg',3)
'efgabcd'
For numpy, just use np.roll
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.roll(a, 1)
array([9, 0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.roll(a, -1)
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
Or you can use a numpy version of the same rotate above (again noting the difference in sign vs np.roll):
def rotate(a,n=1):
if len(a) == 0:
return a
n = -n % len(a) # flip rotation direction
return np.concatenate((a[n:],a[:n]))
A simple and shorthand syntax for array rotation in Python is
arr = arr[numOfRotations:]+arr[:numOfRotations]
Example:
arr = [1,2,3,4,5]
rotations = 4
then
arr = arr[4:]+arr[:4]
gives us
[5,1,2,3,4]
I found a problem that I needed Right and Left rotations for big values of k (where k is number of rotations), so, I implemented the following functions for any size of k.
Right Circular Rotation (left to the right: 1234 -> 4123):
def right_rotation(a, k):
# if the size of k > len(a), rotate only necessary with
# module of the division
rotations = k % len(a)
return a[-rotations:] + a[:-rotations]
Left Circular Rotation (right to the left: 1234 -> 2341):
def left_rotation(a, k):
# if the size of k > len(a), rotate only necessary with
# module of the division
rotations = k % len(a)
return a[rotations:] + a[:rotations]
Sources:
https://stackoverflow.com/a/46846544/7468664
https://stackoverflow.com/a/9457923/7468664
Do you actually need to implement the block swap or are you just looking to rotate the array? In python you can do CW and CWW rotations using
zip(*arr[::-1])
and
zip(*arr)[::-1]
I expect that when you pass a slice of a to your recursive call, you're not passing the same variable any more. Try passing a in its entirety and the upper / lower bounds of your slice as additional arguments to your function.
For instance consider this function:
def silly(z):
z[0] = 2
I just tried the following:
>>> z = [9,9,9,9,9,9]
>>> silly(z)
>>> z
[2, 9, 9, 9, 9, 9]
>>> silly(z[3:])
>>> z
[2, 9, 9, 9, 9, 9]
Where you can see the modification to the slice was not retained by the full array
Out of curiosity, what outputs do you get & what outputs do you expect?
you can use this code for left rotation in python array
import copy
def leftRotate(arr,n) :
_arr = copy.deepcopy(arr)
for i in range(len(arr)-n):
arr[i] = arr[i+n]
for j in range(n):
arr[(len(arr)-n)+j] = _arr[j]
arr = [1, 2, 3, 4, 5, 6, 7]
leftRotateby = 3
leftRotate(arr,leftRotateby)
print arr
#output:: [4, 5, 6, 7, 1, 2, 3]
def leftRotation():
li = [int(x) for x in input().split()]
d = int(input())
ans = (li[d:]+li[0:d])
for i in ans:
print(i,end=' ')
print()
leftRotation()
def rotLeft(a, d):
lenght=len(a)
for j in range(0,d):
temp = a[0]
for i in range(lenght-1):
a[i] = a[i+1]
a[lenght-1] = temp
# Write your code here
return a
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
first_multiple_input = input().rstrip().split()
n = int(first_multiple_input[0])
d = int(first_multiple_input[1])
a = list(map(int, input().rstrip().split()))
result = rotLeft(a, d)
fptr.write(' '.join(map(str, result)))
fptr.write('\n')
fptr.close()
Array Rotation:-
print("Right:1,Left:2")
op=int(input())
par=[1,2]
if op not in par:
print("Invalid Input!!")
else:
arr=list(map(int,input().strip().split()))
shift=int(input())
if op ==1:
right=arr[-shift:]+arr[:-shift]
print(right)
elif op==2:
left=arr[shift:]+arr[:shift]
print(left)
Ouput:-`
Right:1,Left:2
1
12 45 78 91 72 64 62 43
2
[62, 43, 12, 45, 78, 91, 72, 64]`
def rotate(nums=[1,2,3,4,5,6,7], k=3):
i=0
while i < k:
pop_item = nums.pop()
nums.insert(0, pop_item)
i += 1
return nums # [5,6,7,1,2,3,4]
If you are not supposed to use deque or slicing:
def rotate(array: List[int], k: int) -> List[int]:
# loop through the array from -k to array_size - k
return [array[i] for i in range(-k, len(array) - k)]
def rotate(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
result = []
if len(nums) <= 1 : return nums
if k > len(nums): k = K % len(nums)
for i in range(k):
result.insert(0,nums[-1])
nums.pop()
nums = result + nums
return nums
Here, I've used the method of swapping using a temporary variable to rotate an array. As an example, an array 'a' of size 5 is considered. Two variables 'j' and 'i' are used for outer and inner loop iterations respectively. 'c' is the temporary variable. Initially, the 1st element in the array is swapped with the last element in the array i.e a=[5,2,3,4,1]. Then, the 2nd element is swapped with the current last element i.e in this case 2 and 1. At present, the array 'a' would be a=[5,1,3,4,2]. This continues till it reaches the second last element in the array. Hence, if the size of the array is n (5 in this case), then n-1 iterations are done to rotate the array. To enter the no of times the rotation must be done, m is given a value with which the outer loop is run by comparing it with the value of j.
Note: The rotation of array is towards the left in this case
a=[1,2,3,4,5]
n=len(a)
m=int(input('Enter the no of rotations:'))
j=0
while(j<m):
i=0
while(i<n):
c=a[i]
a[i]=a[n-1]
a[n-1]=c
i=i+1
j=j+1
print(a)
This exercise is taken from Google's Python Class:
D. Given a list of numbers, return a list where
all adjacent == elements have been reduced to a single element,
so [1, 2, 2, 3] returns [1, 2, 3]. You may create a new list or
modify the passed in list.
Here's my solution so far:
def remove_adjacent(nums):
if not nums:
return nums
list = [nums[0]]
for num in nums[1:]:
if num != list[-1]:
list.append(num)
return list
But this looks more like a C program than a Python script, and I have a feeling this can be done much more elegant.
EDIT
So [1, 2, 2, 3] should give [1, 2, 3] and [1, 2, 3, 3, 2] should give [1, 2, 3, 2]
There is function in itertools that works here:
import itertools
[key for key,seq in itertools.groupby([1,1,1,2,2,3,4,4])]
You can also write a generator:
def remove_adjacent(items):
# iterate the items
it = iter(items)
# get the first one
last = next(it)
# yield it in any case
yield last
for current in it:
# if the next item is different yield it
if current != last:
yield current
last = current
# else: its a duplicate, do nothing with it
print list(remove_adjacent([1,1,1,2,2,3,4,4]))
itertools to the rescue.
import itertools
def remove_adjacent(lst):
i = iter(lst)
yield next(i)
for x, y in itertools.izip(lst, i):
if x != y:
yield y
L = [1, 2, 2, 3]
print list(remove_adjacent(L))
Solution using list comprehensions, zipping then iterating through a twice. Inefficient, but short and sweet. It also has the problem of extending a[1:] with something.
a = [ 1,2,2,2,3,4,4,5,3,3 ]
b = [ i for i,j in zip(a,a[1:] + [None]) if not i == j ]
This works, but I'm not quite happy with it yet because of the +[None] bit to ensure that the last element is also returned...
>>> mylist=[1,2,2,3,3,3,3,4,5,5,5]
>>> [x for x, y in zip(mylist, mylist[1:]+[None]) if x != y]
[1, 2, 3, 4, 5]
The most Pythonic way is probably to go the path of least resistance and use itertools.groupby() as suggested by THC4K and be done with it.
>>> def collapse( data ):
... return list(sorted(set(data)))
...
>>> collapse([1,2,2,3])
[1, 2, 3]
Second attempt after the additional requirment was added:
>>> def remove_adjacent( data ):
... last = None
... for datum in data:
... if datum != last:
... last = datum
... yield datum
...
>>> list( remove_adjacent( [1,2,2,3,2] ) )
[1, 2, 3, 2]
You may want to look at itertools. Also, here's a tutorial on Python iterators and generators (pdf).
This is also somewhat functional; it could be written as a one-liner using lambdas but that would just make it more confusing. In Python 3 you'd need to import reduce from functools.
def remove_adjacent(nums):
def maybe_append(l, x):
return l + ([] if len(l) and l[-1] == x else [x])
return reduce(maybe_append, nums, [])