Get last and first n elements of a list - python

Need an answer where numbers to leave from the start and end can easily be adjusted.
Thanks.
This is my code:
ls = [1,2,3,4,5,6]
# desired output: [1,2,5,6]
#Tried the following:
ls[-2:2:1]
ls[2:4:-1]
# Both return empty list

If you don't mind modifying the original list in-place you can also delete the slice in the middle:
del ls[2:4]
ls would then become:
[1, 2, 5, 6]
Demo: https://replit.com/#blhsing/StylishFuzzyCopyrightinfringement

Code:-
# [ 0, 1, 2, 3, 4, 5] for positive indices
lis=[ 1, 2, 3, 4, 5, 6]
# [-6,-5,-4,-3,-2,-1] for negative indices
# desired output: [1,2,5,6]
#Some options are
print(lis[:2]+lis[4:])
print(lis[:2]+lis[-2:])
print(lis[-6:-4]+lis[-2:])
print(lis[-6:-4]+lis[4:])
Output:-
[1, 2, 5, 6]
[1, 2, 5, 6]
[1, 2, 5, 6]
[1, 2, 5, 6]

yes you can do slicing like ls[:2] + ls[-2:] to get the desired output

I read the documentation and tried some codes to see why your code fails.
clearly as shown in the documentation there is no problem with the step of slicing being a negative number. I think the problem is that you can not reach the end of the list (or the beginning if your step is negative) and start from the other side.
And for code to work as you want, you can use ls[:2] + ls[-2:] as suggested in the comments

You can parameterize the code to include how many elements you want from the start and end.
For e.g -
ls = [1,2,3,4,5,6]
# desired output: [1,2,5,6]
start = 2 #no of elements needed from start
end = 1 #no of elements needed from end
ls[:start] + ls[-end:] #gives you desired output

Try ls[2:-2] instead of ls[-2:2]

Related

Getting the value of List and sum in python

I newbie in python and I have a trouble how can I make my loop with that shape below and getting the total number of each line, I tried the code below but it seems it doesn't right
I should use list in loop like the declaration below, I appreciate who can help me.
data = [1, 2, 3, 4, 5]
Expected output:
[1, 2, 3, 4, 5, 15]
[2, 3, 4, 5, 14]
[3, 4, 5, 12]
[4, 5, 9]
[5, 5]
This is what I tried but it doesn't use list ,I think it's wrong
data = 5
for i in range(data):
for j in range(i+1):
print("[",j+1, end=" "+" ]")
print("[ ]")
Usually in these kind of exercises you shouldn't build the string yourself(talking about brackets). Those brackets are part of the representation of the lists in Python. So build your list object and the final result is gonna be printed as you expected. So don't attempt to put individual numbers, spaces, brackets together yourself.
You can use:
data = [1, 2, 3, 4, 5]
for i in range(len(data)):
slice_ = data[i:]
print(slice_ + [sum(slice_)])
Explanation:
Basically in every iteration, you create a slice of the list by specifying the start point to the end. Start point comes from the range(len(data)) range object.
first iteration : From index 0 to end.
second iteration: From index 1 to end.
...
Then you concatenate the slice with the sum of the slice. But you have to put the sum inside a list because a list can't be concatenated with an int. Of course other option is to .append() it before printing:
for i in range(len(data)):
slice_ = data[i:]
slice_.append(sum(slice_))
print(slice_)

how to remove a sublist stored in a list in python

I want to create a list using a numpy array. I want to export the differences of the values in the array and also the first value of this array:
my_array=np.array([1, 4, 10])
Firstly I find out the differences:
differs=np.diff(my_array)
it gives me:
array([3, 6])
But I want to have:
[1, 3, 6]
I tried the following:
sep=[my_array[0], np.diff(my_array)]
But it gives me:
[1, array([3, 6])]
I tried also to convert the array into a list but again I have a sublist and I do not know how to only copy the numbers of that sublist into my main list. To do that i tried:
sep=[my_array[0], [i for i in np.diff(my_array)]]
And it gave me:
[1, [3, 6]]
In advance, I do appreciate any help.
You are on right track, you just need to add prepend argument to assign starting value:
np.diff(my_array, prepend=0)
array([1, 3, 6])
I would do it by prepending 0 before feeding to numpy.diff, i.e.:
import numpy as np
my_array=np.array([1, 4, 10])
differs=np.diff(np.hstack(([0],my_array)))
print(differs)
output:
[1 3 6]
Beware that this based solely on your single input-desired output pair, so please test this soultion for other case you might also encounter and write if it does what you want and if not what is actual output and desired output.
try:
sep=[my_array[0], *np.diff(my_array)]
[1, 3, 6]
numpy.diff has a parameter for this:
my_array=np.array([1, 4, 10])
res = np.diff(my_array,prepend=0)
output:
[1 3 6]

Sort a list from an index to another index [duplicate]

This question already has answers here:
Sort a part of a list in place
(3 answers)
Closed 3 years ago.
Suppose I have a list [2, 4, 1, 3, 5].
I want to sort the list just from index 1 to the end, which gives me [2, 1, 3, 4, 5]
How can I do it in Python?
(No extra spaces would be appreciated)
TL;DR:
Use sorted with a slicing assignment to keep the original list object without creating a new one:
l = [2, 4, 1, 3, 5]
l[1:] = sorted(l[1:])
print(l)
Output:
[2, 1, 3, 4, 5]
Longer Answer:
After the list is created, we will make a slicing assignment:
l[1:] =
Now you might be wondering what does [1:], it is slicing the list and starts from the second index, so the first index will be dropped. Python's indexing starts from zero, : means get everything after the index before, but if it was [1:3] it will only get values that are in between the indexes 1 and 3, let's say your list is:
l = [1, 2, 3, 4, 5]
If you use:
print(l[1:])
It will result in:
[2, 3, 4, 5]
And if you use:
print(l[1:3])
It will result in:
[2, 3]
About slicing, read more here if you want to.
And after slicing we have an equal sign =, that just simply changes what's before the = sign to what's after the = sign, so in this case, we use l[1:], and that gives [2, 3, 4, 5], it will change that to whatever is after the = sign.
If you use:
l[1:] = [100, 200, 300, 400]
print(l)
It will result in:
[1, 100, 200, 300, 400]
To learn more about it check out this.
After that, we got sorted, which is default builtin function, it simple sorts the list from small to big, let's say we have the below list:
l = [3, 2, 1, 4]
If you use:
print(sorted(l))
It will result in:
[1, 2, 3, 4]
To learn more about it check this.
After that we come back to our first topic about slicing, with l[1:], but from here you know that it isn't only used for assignments, you can apply functions to it and deal with it, like here we use sorted.
Maybe temporarily put something there that's smaller than the rest? Should be faster than the other solutions. And gets as close to your "No extra spaces" wish as you can get when using sort or sorted.
>>> tmp = l[0]
>>> l[0] = float('-inf')
>>> l.sort()
>>> l[0] = tmp
>>> l
[2, 1, 3, 4, 5]
Benchmarks
For the example list, 1,000,000 iterations (and mine of course preparing that special value only once):
sort_u10 0.8149 seconds
sort_chris 0.8569 seconds
sort_heap 0.7550 seconds
sort_heap2 0.5982 seconds # using -1 instead of -inf
For 50,000 lists like [int(x) for x in os.urandom(100)]:
sort_u10 0.4778 seconds
sort_chris 0.4786 seconds
sort_heap 0.8106 seconds
sort_heap2 0.4437 seconds # using -1 instead of -inf
Benchmark code:
import timeit, os
def sort_u10(l):
l[1:] = sorted(l[1:])
def sort_chris(l):
l = l[:1] + sorted(l[1:])
def sort_heap(l, smallest=float('-inf')):
tmp = l[0]
l[0] = smallest
l.sort()
l[0] = tmp
def sort_heap2(l):
tmp = l[0]
l[0] = -1
l.sort()
l[0] = tmp
for _ in range(3):
for sort in sort_u10, sort_chris, sort_heap, sort_heap2, sort_rev:
number, repeat = 1_000_000, 5
data = iter([[2, 4, 1, 3, 5] for _ in range(number * repeat)])
# number, repeat = 50_000, 5
# data = iter([[int(x) for x in os.urandom(100)] for _ in range(number * repeat)])
t = timeit.repeat(lambda: sort(next(data)), number=number, repeat=repeat)
print('%10s %.4f seconds' % (sort.__name__, min(t)))
print()
Use sorted with slicing:
l[:1] + sorted(l[1:])
Output:
[2, 1, 3, 4, 5]
For the special case that you actually have, according to our comments:
Q: I'm curious: Why do you want this? – Heap Overflow
A: I'm trying to make a next_permutation() in python – nwice13
Q: Do you really need to sort for that, though? Not just reverse? – Heap Overflow
A: Yup, reverse is ok, but I just curious to ask about sorting this way. – nwice13
I'd do that like this:
l[1:] = l[:0:-1]
You can define your own function in python using slicing and sorted and this function (your custom function) should take start and end index of the list.
Since list is mutable in python, I have written the function in such a way it doesn't modify the list passed. Feel free to modify the function. You can modify the list passed to this function to save memory if required.
def sortedList(li, start=0, end=None):
if end is None:
end = len(li)
fi = []
fi[:start] = li[:start]
fi[start:end] = sorted(li[start:end])
return fi
li = [2, 1, 4, 3, 0]
print(li)
print(sortedList(li, 1))
Output:
[2, 1, 4, 3, 0]
[2, 0, 1, 3, 4]

How to reorder a python list backwards starting with the 0th element?

I'm trying to go through a list in reverse order, starting with the -0 indexed item (which is also the 0th item), rather than the -1 indexed item, so that I'll now have the new list to use. I've come up with two ways to do this, but neither seems both concise and clear.
a_list = [1, 2, 3, 4, 5]
print(a_list[:1] + a_list[:0:-1]) # take two slices of the list and add them
# [1, 5, 4, 3, 2]
list_range = range(-len(a_list)+1,1)[::-1] # create an appropriate new index range mapping
print([a_list[i] for i in list_range]) # list comprehension on the new range mapping
# [1, 5, 4, 3, 2]
Is there a way in python 3 to use slicing or another method to achieve this more simply?
If you are up for a programming golf:
>>> a_list = [1, 2, 3, 4, 5]
>>> [a_list[-i] for i in range(len(a_list))]
[1, 5, 4, 3, 2]
I think your first suggestion is the cleanest way of doing this. If you're really optimizing for character count, you can remove two characters from the first slice:
print(a_list[:1] + a_list[:0:-1])
Shift everything left by one and reverse.
my_list.append(my_list.pop(0))
print my_list[::-1]

Python - iterating over lists

I want my code's 2nd function to modify the new list made by my 1st function.
If I am understanding things correctly giving a list as an argument will give the original list (my_list in this case).
so the code removes 1 & 5 and then adds 6, but not 7?
my_list = [1, 2, 3, 4, 5]
def add_item_to_list(ordered_list):
# Appends new item to end of list which is the (last item + 1)
ordered_list.append(my_list[-1] + 1)
def remove_items_from_list(ordered_list, items_to_remove):
# Removes all values, found in items_to_remove list, from my_list
for items_to_remove in ordered_list:
ordered_list.remove(items_to_remove)
if __name__ == '__main__':
print(my_list)
add_item_to_list(my_list)
add_item_to_list(my_list)
add_item_to_list(my_list)
print(my_list)
remove_items_from_list(my_list, [1,5,6])
print(my_list)
output of
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 4, 6, 8]
instead of wanted
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6, 7, 8]
[2, 3, 4, 7, 8]
Thank you and sorry for the elementary question
In your remove_items_from_list function you are iterating through the wrong list. You should iterate through every item in the items_to_remove list like this:
def remove_items_from_list(ordered_list, items_to_remove):
# Removes all values, found in items_to_remove list, from my_list
for item in items_to_remove:
ordered_list.remove(item)
This will now iterate through each item in the remove list and remove it from you ordered_list.
There is a bug in the remove_items_from_list function. For it to achieve what you want it should go:
def remove_items_from_list(ordered_list, items_to_remove):
# Removes all values, found in items_to_remove list, from my_list
for item in items_to_remove:
ordered_list.remove(item)
As a side note, your code has incorrect number of blank lines before function definitions. Should be two blank lines before the function, and not more than one blank line inside functions. It seems not to have affected the code for now, but makes it harder to read, and could cause problems in future.
In the second function you want to iterate over items_to_remove (and not your original list) and then remove every item.
Use:
def remove_items_from_list(ordered_list, items_to_remove):
for item_to_remove in items_to_remove:
ordered_list.remove(item_to_remove)
And don't change the a list when you are iterating over it,which may cause bug.

Categories