what does "+3" represents in [:index+3] in python? - python

Here is the problem statement:
return list[index:]+list[:index+3]
I know [:] represents all the elements of the list.
what does this "+3" represents here?

for this line:
list[:index+3]
if index is set to 1, it is the same as
list[:4]
it's a simple sum on a variable, meaning it will read to 3 positions after your index variable

Every element from [index] till the end plus every element from beginning up to (but not including) [index+3]
Let's have a look at an example:
>>> list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> index=2
>>> list[index:]+list[:index+3]
[3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5]
Here index is 2, thus list[index:]+list[:index+3] is exactly the same as list[index:]+list[0:2+3] which is list[index:]+list[0:5]. So, Every element from [2] till the end plus every element from beginning up to (but not including) [5]

Related

variation of binary search

Say that the target isn't in the list. Instead of outputting -1, I want it to output the rightmost value that's less than the target, followed by the next value (if there is one). In other words, I want to see the gap where the target would be.
If there was a list [1, 2, 4, 7, 7, 8, 9] and I was looking for 5, instead of outputting -1 I want it to output [4, 7]. How do I do that?
Use bisect.bisect to find the insertion point for 5 using binary search, and then take the elements before and after that point:
>>> import bisect
>>> a = [1, 2, 4, 7, 7, 8, 9]
>>> i = bisect.bisect(a, 5)
>>> a[i-1:i+1]
[4, 7]

what's the meaning of x[:]=y? [duplicate]

This question already has answers here:
What is the difference between slice assignment that slices the whole list and direct assignment?
(4 answers)
Closed 6 years ago.
I tried to understand [:] in the beginning, but I can't find any document mention it. Where is the best place to learn advanced grammar for Python? Google search won't find [:]. But I figured it out at the end. I just wonder where is best place to learn Python 'tricks'.
For example:
def test(x, y):
x[:] = y
#x = y
>>> a = [0.5,0.6]
>>> b = [0.3]
>>> test(a, b)
>>>
>>> print a
[0.3] # [0.5,0.6]
x[:] means the entire sequence. It's basically x[from:to].
Omitting from means, from the beginning until the to.
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numbers[:5]
[0, 1, 2, 3, 4]
Omitting to means, from the from until the end.
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numbers[5:]
[5, 6, 7, 8, 9]
Omitting both means the entire list.
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numbers[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Setting numbers[:] means setting the entire list:
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numbers[:] = [1, 2, 3, 4]
>>> numbers
[1, 2, 3, 4]
Keep in mind setting numbers[:] changes that list and does not create a new one. The object will still have the same id().
The term you need to search for is slice. x[start:end:step] is the full form, any one can be omitted to use a default value: start defaults to 0, end defaults to the length of the list, and step defaults to 1. So x[:] means exactly the same as x[0:len(x):1]. You can find more information at
the Expression section of the language reference, and section four of the python tutorial might also be helpful.
The notation x[:] is equivalent to x[0:n] where n is len(x). It specifies the range of elements of x from 0 through n-1 inclusive.
When read, a new list, string, or whatever is created, containing the specified range of elements.
When assigned to, the specified range of elements is destructively replaced in the original. Note that this is allowed for lists, but not for strings.

Smallest number in a particular part of my list

I have a question about python. I have to sort a list of random numbers in a particular way (it's not allowed to use sort()). I'll try to explain:
I have to search for the smallest number, and swap this number with the number at the first position in the list.
Then, I search again for the smallest number, but this time ignore the first number in my list because this one is already sorted. So, I should start searching for the smallest number from the second number (index 1) till the end of the list. The smallest number then found, should be swapped with the second number in the list(so the index 1).
I hope you understand my problem. This is the code I wrote so far, but I get errors and/or the sorting isn't correct.
array = random_integers(10,size=10)
my_list = list(array)
for i in range(len(my_list)):
print my_list
a = min(my_list[i:len(my_list)])
b = my_list.index(a)
my_list[i],my_list[b]=my_list[b],my_list[i]
print my_list
I think there's a problem in my range, and a problem with the
a = min(my_list[i:len(my_list)])
I want to search for the smallest number, but not in the ENTIRE list how can I do this?
The problem occurs on this line:
b = my_list.index(a)
since this searches for the first occurrence of a in all of my_list. If the same number occurs twice, then b will always correspond to the smallest such index, which might be less than i. So you might end up moving a number which has already been sorted.
The obvious thing to try is to slice my_list before calling index:
my_list[i:].index(a)
but note that index will return values between 0 and N-i. We want numbers between i and N. So be sure to add i to the result:
b = my_list[i:].index(a)+i
Thus, the easiest way to fix your code as it presently exists is:
for i in range(len(my_list)):
a = min(my_list[i:])
b = my_list[i:].index(a)+i
my_list[i], my_list[b] = my_list[b], my_list[i]
but notice that min is searching through all the items in my_list[i:] and then the call to index is traversing the same list a second time. You could find b in one traversal like this:
b = min(range(i, N), key=my_list.__getitem__)
Demo:
import numpy as np
array = np.random.random_integers(10,size=10)
my_list = list(array)
N = len(my_list)
for i in range(N):
b = min(range(i, N), key=my_list.__getitem__)
my_list[i], my_list[b] = my_list[b], my_list[i]
print my_list
yields
[3, 10, 9, 6, 5, 3, 6, 8, 8, 4]
[3, 3, 9, 6, 5, 10, 6, 8, 8, 4]
[3, 3, 4, 6, 5, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 10, 6, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 10, 8, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 10, 8, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 10, 9]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
[3, 3, 4, 5, 6, 6, 8, 8, 9, 10]
If you want the smallest number from a list you can use min(). If you want a part of a list you can use list slicing: my_list[1:]. Put the two together and you get the smallest number from a part of your list. However, you don't need to do this, as you can .pop() from the list instead.
sorted_list = []
while my_list:
n = min(my_list)
sorted_list.append(my_list.pop(my_list.index(n)))
If you're using numpy arrays then instead of my_list.index(min(my_list)) you can use the .argmin() method.
While this type of sorting is good for an introduction, it is not very efficient. You may want to consider looking at the merge sort, and also the Python's built-in timsort.

swapping one number with two numbers in a list in python

If I am given a list of numbers and I want to swap one of them with the next two numbers.
Is there a way to do this in one shot, without swapping the first number twice?
To be more specific, let's say I have the following swap function:
def swap_number(list, index):
'''Swap a number at the given index with the number that follows it.
Precondition: the position of the number being asked to swap cannot be the last
or the second last'''
if index != ((len(list) - 2) and (len(list) - 1)):
temp = list[index]
list[index] = list[index+1]
list[index+1] = temp
Now, how do I use this function to swap a number with the next two numbers, without calling swap on the number twice.
For example: I have the following list: list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Now, how do I swap 3 with the 4 and 5 in one shot?
The expected output would be
list = [0, 1, 2, 4, 5, 3, 6, 7, 8, 9]
Something like this?
def swap(lis, ind):
lis.insert(ind+2, lis.pop(ind)) #in-place operation, returns `None`
return lis
>>> lis = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> lis = swap(lis, 3)
>>> lis
[0, 1, 2, 4, 5, 3, 6, 7, 8, 9]

Why following code doesn't give "IndexError"?

I have following python code:
a = [0,1,2,3,4,5]
del(a[2:7])
Should not this give "IndexError"? If no then why?
This deletes the list slice from 2 to before 7. List slices do not throw index errors, rather if they extend beyond the end of the list, they return the whole remainder of the list.
>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a [5:20]
[5, 6, 7, 8, 9]

Categories

Resources