Python - Swap consecutive elements of a list? [duplicate] - python

This question already has answers here:
Wrapping around a list as a slice operation
(4 answers)
Closed 6 years ago.
I want to swap the consecutive elements of a list such that the first element will go to the last. eg [4, 7, 3, 4, 3] should print as [7,3,4,3,4]
This is the code I've written but it doesn't work right. How can I modify it to get it working?
ls = [4, 7, 3, 4, 3]
i=0
b=1
while i+1<len(ls):
ls[i]=a
ls[i]=ls[i+1]
ls[i+1]=a
i+=1
print ls
I do not want to just switch the first element with the last one. I want to modify this code further to create a bubble sort algorithm, I am just confused at how to get done what I just explained.
Updated : Thanks for the answer that I should change "ls[i]=a" with "a=ls[i]", but can someone explain to me how this differs in logic?

You don't need a loop to move the first element to the last. Just pop the first element off the list, then append it.
ls.append(ls.pop(0))

Python allows to work with lists by selecting one or several elements at the time and to concatenate the content of the list
ls = [4, 7, 3, 4, 3]
new_list_with_first_element_at_the_end = ls[1:] + [ls[0]]

If you really feel you must, make a swap function:
def swap(l, i, j):
tmp = l[j]
l[j] = i
l[i] = tmp
Then you can:
for i in range(len(l)-1):
swap(l, i, i+1)

Related

Python Slicing Issue: every other element in list, starting with last element not working?

so I have a list of numbers, and I want to start at the last element of the list and print every other element.
So given list = [1, 2, 3, 4, 5, 6] I would print 6, 4 and 2. My issue is that slicing is not printing the last element.
list = [1, 2, 3, 4, 5, 6]
for i in list[-1::-2]:
print(list[i])
this merely prints 4 and 2, showing me that the last digit is not included. I have also tried omitting the -1 and just using list[::-2]. It takes every odd digit (4 and 2) but does not include 6. I want to use slicing to achieve this result, but clearly I am misunderstanding how to use it. Any help much appreciated (this is my first stackOverflow question btw!)
Please avoid using the variable names as a list.
ls = [1, 2, 3, 4, 5, 6]
for i in ls[-1::-2]:
print(i)
You're iterating all the elements of the list using the in method. It doesn't provide you an index that you will use to print.
When you're trying to print list[i] it will raise an error because when i=6 then list[i] element don't exist in the list.
You can simply do slicing by using:
ls = [1, 2, 3, 4, 5, 6]
print(ls[-1::-2])
and don't use the list as a variable name because it is a keyword in Python so you will get an error.
Have you tried printing just i instead of the list[i]?
You should remember here that if you iterate through a reversed list, you need not do indexing again. The i would hold the value of the list element.
Please try:
for i in ls[::-2]:
print(i)

How to parse these operations through lists?

Program description:
Program accepts a list l containing other lists. Output l where lists with length greater than 3 will be changed accordingly: the element with index 3 is going to be a sum of removed elements (from third to the end).
My solution:
l = [[1,2], [3,4,4,3,1], [4,1,4,5]]
s = 0
for i in range(len(l)-1):
if len(l[i]) > 3:
for j in range(3,len(l[i])-1):
s += l[i][j]
l[i].remove(l[i][j])
l[i].insert(len(l[i]),s)
l
Test:
Input: [[1,2], [3,4,4,3,1], [4,1,4,5]]
Expected Output: [[1, 2], [3, 4, 8], [4, 1, 9]]
Program run:
Input: [[1,2], [3,4,4,3,1], [4,1,4,5]]
Output: [[1, 2], [4, 4, 3, 1, 3], [4, 1, 4, 5]]
Question: I don't understand what can be the source of the problem in this case, why should it add some additional numbers to the end, instead of summ. I will appreciate any help.
remove is the wrong function. You should use del instead. Read the documentation to understand why.
And another bug you have is that you do not reset s. It should be set to 0 in the outer for loop.
But you're making it too complicated. I think it's better to show how you can do it really easy.
for e in l: # No need for range. Just iterate over each element
if len(e) > 3:
e[2]=sum(e[2:]) # Sum all the elements
del(e[3:]) # And remove
Or if you want it as a list comprehension that creates a new list and does not alter the old:
[e[0:2] + [sum(e[2:])] if len(e)>3 else e for e in l]
First of all, remove() is the wrong method, as it deletes by value, not index:
Python list method remove() searches for the given element in the list
and removes the first matching element.
You'd want to use del or pop().
Second of all, you're not slicing all of the elements from the end of the list, but only one value.
remove is reason why your code is not working. (as mentioned by Mat-KH in the other answer)
You can use list comprehension and lambda function to make it a two liner.
func = lambda x: x if len(x) < 3 else x[:2] + [sum(x[2:])]
l = [func(x) for x in l]

Select only one values from continuous occurrences of values in a list [duplicate]

This question already has answers here:
Removing elements that have consecutive duplicates
(9 answers)
Closed 3 years ago.
I have a list like this,
l=[1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,5,6,6,6,5,5,5,7,7,8,8,8,8,8,9,9,9,10,10]
Now I want to select only one values of repeating value continuously, so the output should look like,
l=[1,2,3,4,5,6,5,7,8,9,10]
I could do this using a for loop checking the next values with the previous and append to a list, But the execution time is huge in that case, Looking for shortcuts to do it most efficiently.
You can use itertools.groupby to group consecutive values and keep only the grouping key:
from itertools import groupby
[k for k,_ in groupby(l)]
# [1, 2, 3, 4, 5, 6, 5, 7, 8, 9, 10]
Use the set data structure to remove duplicates and convert it back to a list:
l = [1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,5,6,6,6,5,5,5,7,7,8,8,8,8,8,9,9,9,10,10]
# remove duplicates
num = set(l)
# convert the set of unique values back to a list
num = list(num)
print(num)
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
You can use itertools.groupby or something like this (I haven't used zip or slices on purpose and tried to keep it as simple as possible)
def group_by(array):
if not array:
return array
prev = array[0]
result = [prev]
for el in array:
if el != prev:
result.append(el)
prev = el
return result
P.S. Yes, with zip or enumerate or islice it can be more elegant, I know :-)

Sum all list-elements to new list [duplicate]

This question already has answers here:
How to find the cumulative sum of numbers in a list?
(25 answers)
Closed 6 years ago.
I have an old list and I want to sum up every single element to a new list:
lst_old = [1, 2, 3, 4, 5]
lst_new = [1, 3, 6, 10, 15]
Is there an elegant way to implement that in Python 3 with short and fast code? Apart from sum() which only prints last element I couldn't find a proper solution for my problem.
You can use itertools.accumulate, eg:
from itertools import accumulate
lst_old = [1, 2, 3, 4, 5]
lst_new = list(accumulate(lst_old))
# [1, 3, 6, 10, 15]
itertools.accumulate as mentioned by Jon Clements is the best way to do. However, in case you want an explicit way to do it, here goes:
lst_old = [1, 2, 3, 4, 5]
sum = 0
lst_new = []
for item in lst_old:
sum += item
lst_new.append(sum)
Main advantage of this is, you can wrap it in a function and if there is any transform or validation need to be performed, can be added.
For example, lets say you want to stop the function keep going after a limit, the following will help:
def accumulate_items(lst_old, limit=0):
sum = 0
output_list = []
for item in lst_old:
sum += item
output_list.append(sum)
if limit and sum > limit:
break
return output_list
The flexibility will be limitless if there is any transformation or operation need to be done here. Have a pre-condition that need to be set? Go ahead. Have a post-condition that need to be tested? Go ahead. Pretty huge list and wanted a generator based solution just like the itertools.accumulate? Go ahead. Need to add a validation or exception handling? Go ahead.
However, no transformation and simply accumulate? The previous answer is the best. Using sum with list indices is pretty slow as the order of complexity sky rockets.
You can take the sum of a slice of a list using listname[start:end], with both start and end as optional arguments (defaulting to the beginning and end of the list):
lst_old = [1, 2, 3, 4, 5]
lst_new = []
for i, num in enumerate(lst_old):
index = i+1
var = sum(lst_old[:index])
print(var)
lst_new.append(var)

Elegant Way of Ignoring Specific Python ListElements [duplicate]

This question already has answers here:
Get unique values from a list in python [duplicate]
(30 answers)
Closed 6 years ago.
I have recently started trying to learn Python, and I try to improve the way I write code, and make it more "Pythonic".
Therefore, it would really be nice if someone could explain to me if the following can be formulated more elegantly.
Hopefully this is not a duplicate (I checked, but you never know)
I have a list of 5 elements, and I want to return specific elements.
Let's say for example that I have [1, 2, 3, 3, 4].
I already have a function double(list), that if a list element exists twice returns that element (in this case 3).
I would like to generate from this list a tuple that contains the numbers that are exist only once (1, 2, 4).
One option is the following:
Run the double(list) function and get the value of the element that is double.
Create an empty tuple
Iterate over the list items, and if the value is not equal to what the double(list) function returned, add it to the tuple
Return the tuple.
My question is: is there a more elegant/Pythonic way of doing this?
(in one line, using maybe a more complex expression?)
Thanks in advance
The general way to do this is to make a set out of the elements and then count them, or just use collections.Counter, then go through the list and include only the appropriate elements, by either creating an empty list and then adding to it with a traditional loop or by using a comprehension with a filter.
>>> import collections
>>> l = [1, 2, 3, 3, 4]
>>> c = collections.Counter(l)
>>> new_list = [item for item in l if c[item] < 2]
>>> new_list
[1, 2, 4]
Since you want a single-line solution (well except for the actual list declaration of course :) ):
your_list = [1, 2, 3, 3, 4]
uniques = [item for item in your_list if your_list.count(item) == 1]
I would use collections.Counter for that:
>>> import collections
>>> l = [1, 2, 3, 3, 4]
>>> c = collections.Counter(l)
>>> [el for el in l if c[el] == 1]
[1, 2, 4]

Categories

Resources