Change the position of the value in my list - python

Im trying to find a way to change the order of my list at the end.
For example, for a list of 4 boxes, we invert the values ​​of boxes 1 and 2 and we reverse the values ​​of boxes 3 and 4.
normal_list([1, 2, 3, 4]) I want the first number to be even and the second to be odd like this :
[2, 1, 4, 3]
creating an empty list
lst = []
# number of elemetns as input
n = int(input("Enter an even number: "))
if (n % 2) == 0:
print("Enter the desired",n, "numbers : ".format(n))
else:
print("Please enter an even number")
# iterating till the range
for i in range(0, n):
if n % 2 == 0:
ele = int(input())
lst.append(ele) # adding the element
else :
break
print('this is the list : ',lst)
def Split(mix):
ev_li = []
od_li = []
for i in mix:
if (i % 2 == 0):
ev_li.append(i)
else:
od_li.append(i)
print("This is the new list:", ev_li + od_li)
mix = lst
Split(mix)

There are many ways to do this. You can loop over pairs of indexes by zipping a range() iterator. This will allow you to swap the values in place:
l = [1, 2, 3, 4]
e = iter(range(len(l)))
for a, b in zip(e, e): # pairs of indexes like (0, 1), (2, 3)...
l[a], l[b] = l[b], l[a]
print(l)
# [2, 1, 4, 3]
Alternatively, you could make a new list with a list comprehension by zipping the list with itself into pairs and then reversing the pairs:
l = [1, 2, 3, 4]
new_l = [n for pair in zip(l[::2], l[1::2]) for n in reversed(pair)]
print(new_l)
# [2, 1, 4, 3]
The behavior is not really specified when the list is not an even length.

#Mark Meyer has given a terrific answer, but here are a couple of the alternatives he spoke of:
A very explicit swapper:
l = [1, 2, 3, 4]
for p in range(0,len(l),2):
l[p],l[p+1]=l[p+1],l[p]
print (l)
And the truly awful:
l = [1, 2, 3, 4]
l = [l[p^1] for p in range(len(l))]
print (l)
I leave it to the reader to figure out that last one.

You can loop through an even list and an odd list at once using zip() to do this.
old_list = [1,2,3,4,5,6]
# Make empty list of same length
new_list = []
even = []
odd = []
for item in old_list:
# Check if even
if item % 2 == 0:
even.append(item)
else:
odd.append(item)
# Loop through both lists at once
for e, o in zip(even, odd):
# add the even item first
new_list.append(e)
# then add the odd
new_list.append(o)
print(new_list) # Returns: [2,1,4,3,6,5]

Related

Merge two sorted arrays using for loop is missing the last item

I m new to dealing with algorithms and my challenge was to merge two sorted lists into one using for loop not while loop. I got stuck at determining the end of the list:
list1=[1,2,4]
list2=[1,3,4,6]
def mergeTwoLists(list1: list, list2:list) -> list:
l = 0
r = 0
lRange = len(list1)-1
rRange = len(list2)-1
total_range = (len(list1)+len(list2))-1
merger = []
for i in range(total_range):
if list1[l]<=list2[r]:
merger.insert(i,list1[l])
if l<lRange:
l+=1
elif list1[l]>list2[r]:
merger.insert(i,list2[r])
if r<rRange:
r+=1
return(merger)
It returns [1,1,2,3,4,4] and missing the last value 6.
Following works for different kinds of lists. It gets items from the lists in an asynchronous manner and breaks out of loop when length of any one list is finished. Finally, it appends any excess items from the other list.
def mergeSortedLists(l1, l2):
outlist =[]; i=0; j=0;
while i<len(l1) and j<len(l2):
a = l1[i]; b = l2[j]
if a<b:
outlist.append(a); i+=1
else:
outlist.append(b); j+=1
outlist += l1[i:] + l2[j:]
print(outlist)
Try:
list1=[1,2,4]
list2=[1,3,4,6,7]
mergeSortedLists(list1, list2)
output:
[1, 1, 2, 3, 4, 4, 6, 7]
Or:
list1=[1,2,3]
list2=[4,5,6,8]
mergeSortedLists(list1, list2)
Output:
[1, 2, 3, 4, 5, 6, 8]
You're missing the last element because you subtract 1 when creating total_range.
You need to test which index is still within range inside the loop. You can only compare elements while both indexes are in range for their respective lists. Once you reach the end of one of the lists, just copy the rest of the other list to the result.
def mergeTwoLists(list1: list, list2:list) -> list:
l = 0
r = 0
lRange = len(list1)
rRange = len(list2)
total_range = lRange + rRange
merger = []
for i in range(total_range):
if l < lRange and r < rRange:
if list1[l]<=list2[r]:
merger.append(list1[l])
l+=1
elif list1[l]>list2[r]:
merger.append(list2[r])
r+=1
elif l < lRange:
merger.extend(list1[l:])
break
else:
merger.extend(list2[r:])
break
return(merger)
list1=[1,2,4]
list2=[1,3,4,6]
print(mergeTwoLists(list1, list2))

how to check weather an element appear only once in a list in python? [duplicate]

This question already has an answer here:
Check for unique numbers and extract index
(1 answer)
Closed 8 months ago.
How can I write a function to compute the numbers that appear only once in a list like [2, 1, 2, 5, 2, 1, 1, 3]. If more than two numbers are founded, it should return the smallest number and if there is no number with the one-time appearance it should return "Not found".
This is the code that I have written:
def one_time(nums, n):
nums.sort()
if nums[0] != nums[1]:
print(nums[0], end = " ")
for i in range(1, n - 1):
if (nums[i] != nums[i + 1] and
nums[i] != nums[i - 1]):
print( nums[i])
if nums[n - 2] != nums[n - 1]:
print(nums[n - 1], end = " ")
if __name__ == "__main__":
nums = [2, 1, 2, 5, 2, 1, 1, 3]
n = len(nums)
one_time(nums, n)
collections.Counter is the way most people determine how many of each item are in a list. Once you have counts, you can filter by those numbers with only 1 (that the if v == 1 part), sort and take the next() value. next() offers the ability to provide a default if nothing is found:
from collections import Counter
l = [2, 1, 2, 5, 1, 1, 3]
next((k for k,v in sorted(Counter(l).items()) if v == 1), "Not Found")
# 3
# with no unique elements
l = [2,2,1,1]
next((k for k,v in sorted(Counter(l).items()) if v == 1), "Not Found")
# 'Not Found'
Use collections.Counter to count the list elements, and convert into a dictionary with keys = elements of the original list lst and values = their number of occurrences in that list.
Use list comprehension to select only the elements that occurred exactly once.
Select the minimum number from that list.
from collections import Counter
lst = [2, 1, 2, 5, 2, 1, 1, 3]
cnt = dict(Counter(lst))
print(cnt)
# {2: 3, 1: 3, 5: 1, 3: 1}
try:
smallest_once = min([x for x, c in cnt.items() if c == 1])
print(smallest_once)
except ValueError:
print("Not found")
# 3
If it were me, I'd use two sets: one to store the numbers that still might be singles, and one to store the numbers I've found before. As soon as a number is in the "seen before" list, I can remove it from the singles:
def one_time(nums):
single = set(nums)
multi = set()
for n in nums:
if n in multi and n in single:
single.remove(n)
multi.add(n)
return list(single)
if __name__ == "__main__":
nums = [2, 1, 2, 5, 2, 1, 1, 3]
print(min(one_time(nums)))
You can create a set using the list with a different name (e.g. myset = set(mylist))
Then loop through the set and use the built in
.count() function on each element in the set.
Make a variable called counter or something that makes sense and initialize it to zero.
For each iteration, if there is a number that only appears once and counter is equal to zero, save thr number in counter (or a different variable if 0 is a possible number in the list)
If there is another number that appears once, check it's value against the previously saved number.
I hope this helps, and I hope it makes sense, I'm quite tired right now. Good luck.

Finding all elements greater than current element in a list

If I have an array in Python in which all of the elements have different values, e.g. [1,4,6,2,10,3,5],
is there a way to find the total number of values in the list that are greater than the current index?
So for example, using the above list of length 7, the result I'd like to get is another list of length 7 which looks like [6,3,1,5,0,4,2]. I was having trouble trying to loop through the list (the code I tried to use is below)
for i in data:
count = np.sum(data > data[i])
N[i]=count
where data is the array containing all the pertaining values and N is an np.zeros list of the same length as data
You were very close. for i in data iterates through each element, not the indices as in Java/C.
Use range(len(data)) instead.
import numpy as np
data = np.array([1,4,6,2,10,3,5])
out = np.array([0]*7)
for i in range(len(data)):
count = np.sum(data > data[i])
out[i] = count
print(out) # [6 3 1 5 0 4 2]
Another way to write the loop is to use enumerate(), which returns an iterator of pairs of (indices, elements).
for i, x in enumerate(data):
count = np.sum(data > x)
out[i] = count
Here is my suggestion:
We sort the original list (l) and save it in a new list m. We create a new list (k) where we save the count of elements that are found on the right of the position of each element in m. See below:
l=[1,4,6,2,10,3,5]
m=sorted(l)
#[1, 2, 3, 4, 5, 6, 10]
k=[]
for i in l:
k.append(len(m)-m.index(i)-1)
>>> print(k)
[6, 3, 1, 5, 0, 4, 2]
Something like this?
list = [1,4,6,2,10,3,5]
list2 = []
v = len(list)
for x in list:
if x > v:
pass
else:
list2.append(x)
print(list2)
EDIT ¯\_(ツ)_/¯ (To see the total number of elements greater than the current element)
list = [1,4,6,2,10,3,5]
list2 = []
v = len(list)
total = 0
for x in list:
if x > v:
pass
else:
list2.append(x)
for y in list2:
total += 1
list2 = str(list2).replace('[', '')
list2 = list2.replace(']', '')
print("Now - " + list2 + ", in total of " + str(total) + " numbers ;)")
Output -
Now - 1, 4, 6, 2, 3, 5, in total of 6 numbers ;)
Alternatively, you can do it by using vectorize as follows:
>>> data = np.array( [1,4,6,2,10,3,5] )
>>> np.vectorize(lambda a, b : np.sum(a>b), excluded = [0] )(data, data)
array([6, 3, 1, 5, 0, 4, 2])

How to find unique elements in a list in python? (Without using set)

Write a function that accepts an input list and returns a new list
which contains only the unique elements (Elements should only appear
one time in the list and the order of the elements must be preserved
as the original list. ).
def unique_elements (list):
new_list = []
length = len(list)
i = 0
while (length != 0):
if (list[i] != list [i + 1]):
new_list.append(list[i])
i = i + 1
length = length - 1
'''new_list = set(list)'''
return (new_list)
#Main program
n = int(input("Enter length of the list: "))
list = []
for i in range (0, n):
item = int(input("Enter only integer values: "))
list.append(item)
print ("This is your list: ", list)
result = unique_elements (list)
print (result)
I am stuck with this error:
IndexError: list index out of range
This is the simplest way to do it:
a = [1, 2, 2, 3]
b = []
for i in a:
if i not in b:
b.append(i)
print (b)
[1, 2, 3]
The problem with your code is that you are looping length times but checking list[i] with list[i+1], thus accessing an element past the end of the input list (e.g. in a list with 6 elements there are 6-1=5 pairs of consecutive elements).
A second issue with your code is that an input with only one element [1] should give as output [1] even if this element is not different from any other. The input text means you should remove elements that are equal to other elements already present, not that you should keep elements that are different from the next one.
Another issue is that you're only checking for consecutive duplicates i.e. given the input list [1, 2, 1, 2] your logic wouldn't detect any duplication... looks like the exercise instead requires in this case as output of [1, 2].
A trace for a simple algorithm to do this is
for each element in input
if the element has not been included in output
add the element to the end of output
Note also that to check if an element is present in a list Python provides the in operator (e.g. if x in output: ...) that can save you an explicit loop for that part.
As a side note naming an input parameter list is considered bad practice in Python because list is the name of a predefined function and your parameter is hiding it.
O(n) solution without using a set:
>>> from collections import Counter, OrderedDict
>>> class OrderedCounter(Counter, OrderedDict):
... pass
...
>>> lst = [1, 2, 2, 3, 4, 5, 4]
>>> [x for x,c in OrderedCounter(lst).items() if c==1]
[1, 3, 5]
One line implementation:
list = [100, 3232, 3232, 3232, 57, 57, 90]
new_list = []
[new_list.append(x) for x in list if x not in new_list]
print(new_list)
Prints:
[100, 3232, 57, 90]
The problematic line is > if (list[i] != list [i + 1]): < (6th line in your code).
Reason:
Imagine your list has got 4 elements.
Eg: mylist = [ 1, 2,2,3].
mylist[i] != mylist [i + 1]
In the last iteration 'i' will be 4 , so i + 1 will be 5.
There is no such 5th index in that list, because list indexes are counted from zero.
mylist[0] = 1
mylist[1] = 2
mylist[2] = 2
mylist[3] = 3
mylist[4] = No Index
mylist[5] = No Index
def unique_elements (list):
new_list = []
# Replace the while with a for loop**
for i in list:
if i not in new_list:
new_list.append(i)
return (new_list)
#Main program
n = int(input("Enter length of the list: "))
list = []
for i in range (0, n):
item = int(input("Enter only integer values: "))
list.append(item)
print ("This is your list: ", list)
result = unique_elements (list)
print (result)
l = [1, 2, 2, 3,4,5,6,5,7,8]
myList = []
[ myList.append(item) for item in l if item not in myList]
print(myList)
Use of collections is best IMO,
Accepted answer is simplest,
Adding another approach using dict where you can check frequency as well,
text = [100, 3232, 3232, 3232, 57, 57, 90]
# create empty dictionary
freq_dict = {}
# loop through text and count words
for word in text:
# set the default value to 0
freq_dict.setdefault(word, 0)
# increment the value by 1
freq_dict[word] += 1
unique_list = [key for key,value in freq_dict.items()]
print(unique_list )
print(freq_dict )
[100, 3232, 57, 90]
{100: 1, 3232: 3, 57: 2, 90: 1}
[Program finished]
You can also print by values based on requirements.
So if you are at the last element, then if (list[i] != list [i + 1]): will try to take a value out of the list which is not present there and that is why the error is showing that the list is out of range.
You can work this out using sets and set comprehension syntax is in most cases overlooked. Just as lists sets can also be generated using comprehension.
elements = [1, 2, 3, 3, 5, 7, 8, 7, 9]
unique_elements = {element for element in elements}
print(unique_elements)
Found an easier approach for people on Python 3.7.
Using a dictionary:
list(dict.fromkeys(mylist))

How to find the smallest missing numbers from a list without using inbuilt functions or modules

Here is my list:
List = [[1,2,4,5], [1,2,3,4,5,7], [1,4,5,6], [2,3,5], [1,2,3]]
From this how to find all the smallest missing numbers?
Edit:
The "smallest missing number" is the first integer (> 0) that is not in the list.
The expected output for the example input is 3, 6, 2, 1 and 4.
The input lists are always sorted.
An approach without any built-in functions:
Lists = [[1,2,4,5],[1,2,3,4,5,7],[1,4,5,6]]
for List in Lists:
i = 1
while i <= List[-1] + 1:
if i in List:
i += 1
else:
break
print i
Basically it processes each List separately (is that what you want?). It iterates a counter i starting at 1 (assuming you look for integers > 0) and stops, as soon as List doesn't contain i.
Output:
3
6
2
If the sublists are already sorted like you input, just compare the previous to the current element, if the prev +1 is not equal to the current ele add prev + 1 to the output list:
List = [[1, 2, 4, 5], [1, 2, 3, 4, 5, 7], [1, 4, 5, 6]]
out = []
for sub in List:
prev = sub[0]
for ele in sub[1:]:
if prev + 1 != ele:
out.append(prev +1)
break
prev = ele
print(out)
[3, 6, 2]
It will work for any sublists that are ordered not just lists starting with 1:
List = [[3, 4, 5,7], [10,13,14,15], [100,101,104,105]]
Output:
[6, 11, 102]
And without slicing:
out = []
for sub in List:
prev = sub[0]
i = 0
for ele in sub:
if i == 0:
i += 1
continue
if prev + 1 != ele:
out.append(prev +1)
break
prev = ele
print(out)
If you always want to find the first missing number starting at 1 and can have 0 or negative numbers, only check each ele and increase i if the ele is > 0:
out = []
for sub in Lists:
i = 1
for ele in sub:
if ele > 0:
if ele != i:
out.append(i)
break
i += 1
print(out)
That means at worst you do a single pass over each sublist as opposed to O(n^2) approach using in
Inspired by this answer:
List = [[1,2,4,5],[1,2,3,4,5,7],[1,4,5,6]]
print [sorted(set(range(1,max(l)+2)).difference(l))[0] for l in List]
Output:
[3, 6, 2]
Sure, this approach uses built-in functions. But you can start from here and break it down by replacing forbidden functions by your own implementations.

Categories