Selection sort using python3 - python-3.x

def selection_sort(li):
new_list = []
a = li[0]
for x in range(1, len(li)):
if li[x] < a:
a = li[x]
new_list = a
print(new_list)
b = [1, 2, 5, 3, 7, 4]
selection_sort(b)
Why does the above code returns empty list.
Thank you

Learn what is selection sort using visualization. Do follow the steps how to use selection sort
def selection_sort(li):
for i in range(len(li)):
min_idx = i
for j in range(i+1, len(li)):
if li[min_idx] > li[j]:
min_idx = j
li[i], li[min_idx] = li[min_idx], li[i]
print(li)
b = [1, 2, 5, 3, 7, 4]
selection_sort(b)
Now, from your code perspective, your selection sort algorithm isn't correct. Furthermore, you don't need to initialize another list to store sort element rather your function parameter list is kind enough to store the sort element.

Related

If there is a duplicate in a list, how do I delete ALL occurrences of item? [duplicate]

I have a list like this:-
[1,2,3,4,3,5,3,6,7,8]
I want to remove the repeating element (here:- 3) completely from the list like this:-
[1,2,4,5,6,7,8]
How do I implement this in python such that not only the first occurrence of duplicate element is removed but all the duplicating values are removed
You can use Counter from collections to count the number of occurrences and select those elements which appear exactly once using a list comprehension:
from collections import Counter
a = [1,2,3,4,3,5,3,6,7,8]
[k for k, v in Counter(a).items() if v == 1]
(Counter basically returns a dictionary where elements are stored as keys and their counts are stored as values.)
This code should work
#Finding duplicate
def dup(x):
s = len(x)
duplicate = []
for i in range(s):
k = i + 1
for j in range(k, s):
if x[i] == x[j] and x[i] not in duplicate:
duplicate.append(x[i])
return duplicate
#begining
list1 = [1, 2, 3, 4, 3, 5, 3, 6, 7, 8]
#Finding duplicate
dup_list = (dup(list1))
#removing duplicates from the list
final_list = list(set(list1) - set(dup_list))
print(final_list)
A good and efficient way will be to use pandas
import pandas as pd
sample_list = [1,2,3,4,3,5,3,6,7,8]
unique_list = list(pd.Series(sample_list).drop_duplicates())
>> unique_list
>> [1, 2, 3, 4, 5, 6, 7, 8]
Use a set. To get rid of all repeating values use this:
a = [1,2,3,4,3,5,3,6,7,8]
print(a)
a = list(set(a))
print(a)
That will output
[1,2,3,4,3,5,3,6,7,8]
[1,2,4,5,6,7,8]

Python} Reversing List Without Using String Method

How should I write the code with the following problem?
Implement the function reverse_print(lst) that prints out the contents of the given list ‘lst’
in reverse order. For example, given a list [3, 6, 2, 1], the output should be 1, 2, 6, 3 (vertical
printout allowed). For this code, you are only allowed to use a single for-loop. Without String Method
Also Not using Print[::-1]
Assuming you are not allowed to just call list.reverse() you can use range with a negative step to iterate the list in reverse order:
def reverse_print(lst):
out = []
for i in range(len(lst) - 1, -1, -1):
out.append(lst[i])
print(*out, sep=", ")
inp = [1, 2, 3, 4]
reverse_print(inp)
Output: 4, 3, 2, 1
You may try something like this
def reverse_print(lst):
rev = [lst[abs(i-l)-1] for i in range(l)]
return rev
lst = [3,6,2,1]
l = len(lst)
print(reverse_print(lst))

How to print list of numbers in square matrix?

l1 = [4, 8, 12,16,3,7,11,15,2,6,10,14,1,5,9,13]
output :
[4,8,12,16]
[3,7,5,11]
[1,6,10,14]
[1,5,9,13]
m =4
n=4
tmp = [[0]*m]*n
a = 0
for i in range(m):
for j in range(n):
tmp[i][j] = l1[a]
a += 1
not printing in required format.
What's wrong here ? Can you please help me.
You could achieve this with the following list of comprehension:
list1 = [4, 8, 12,16,3,7,11,15,2,6,10,14,1,5,9,13]
[list1[x:x+4] for x in list(range(0,len(list1),4))]
Output
[[4, 8, 12, 16], [3, 7, 11, 15], [2, 6, 10, 14], [1, 5, 9, 13]]
The issue with the code is the array initialization part.
tmp = [[0]*m]*n This will create a common memory address and whatever changes you are making to one index will be reflected to other index as well.
So to initialize the list you can use the following code
tmp = [[0 for _ in range(m)] for _ in range(n)]
The simple method is already shared by #Sebastien D
You just need to change the way you initialize your tmp matrix
tmp = [[[0] for _ in range(m)] for _ in range(n)]
Iterate through the initial list with step of m and every time append list of m elements to the final list where m is number of elements in each row.
t = []
for i in range(0, len(l1), m):
t.append(l1[i:i+m])
print(t)

To make odd position in list go forward for one step

I found this code from stackoverflow ... and wondering how can I move index position that I want.
I tried to use for loop and [::1]. And by making, len(a)*[0]...I couldn't make it.
Is there any way to fix items on its position in list?
Second, without using method below, is there another way to reorder items in list?
'''
mylist=['a','b','c','d','e']
myorder=[3,2,0,1,4]
'''
a = [1,2,3,4,5,6,7]
b = ((a+a[:0:-1])*len(a))[::len(a)][:len(a)]
[1, 7, 2, 6, 3, 5, 4] <=b
[7, 1, 6, 2, 5, 3, 4] <= the result i want
Thanks in advance.
I'm not sure if this is what you want:
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
reversedOrderedList = orderedList[::-1]
finalList = []
for i in range(len(someList)):
if i % 2 == 0:
finalList.append(reversedOrderedList[i//2])
else:
finalList.append(orderedList[i//2])
print(finalList)
output:
[7, 1, 6, 2, 5, 3, 4]
if so, you can write it in shorter way (without reversedOrderedList):
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
finalList = []
for i in range(len(someList)):
if i % 2 == 0:
finalList.append(orderedList[-1-i//2])
else:
finalList.append(orderedList[i//2])
print(finalList)
and from here you can write it without if statement:
someList = [1,2,3,4,5,6,7]
orderedList = sorted(someList)
for i in range(len(someList)):
finalList.append(orderedList[((-1)**(i%2+1)-1)//2 + ((- 1)**(i%2+1))*(i//2)])
print(finalList)
It is not pretty but after that you can easily write a generator.
Zip the list with its reversed version, flatten it and take the first half:
from itertools import chain
a = [1,2,3,4,5,6,7]
b = list(chain.from_iterable(zip(a[::-1], a)))
print(b[:len(b) // 2])
Output
[7, 1, 6, 2, 5, 3, 4]

List Comprehensions to replace element

for i in range(1, len(A)):
A[i] = A[i-1] + A[i]
You can't do that with a list comprehension as they don't allow assignments.
You can use a simple generator function:
def func(lis):
yield lis[0]
for i,x in enumerate(lis[1:],1):
lis[i] = lis[i-1] + x
yield lis[i]
>>> A = [1, 2, 3, 4, 5, 6, 7]
>>> list(func(A))
[1, 3, 6, 10, 15, 21, 28]
though less efficient, this does give the desired output. But I think I'm getting closer to O(n**2) on this one.
A = [sum(A[:i+1]) for i, _ in enumerate(A)]
afaik this can't be done with a list comprehension the way you want to. I would suggest using the for loop version you've provided. Even if it was possible with a list comprehension, there's no point when you can just modify the list in place.
Use B (another temporary variable).
This should do the trick.
def func(L):
it = iter(L)
v = it.next()
yield v
for x in it:
v += x
yield v
A = [1, 2, 3, 4, 5, 6, 7]
print list(func(A))
This creates an iterator that returns one value at the time. To get the full new list at once you need to use a list() call around the function call, like:
list(func(A))
This generator function should work on any iterable (also those that don't support getting value based on index, like L[0])
I don't think there's an efficient way to do this with a comprehension list.
A one-line solution use reduce:
>>> the_list = [1,2,3,4,5]
>>> reduce(lambda result, x: result+[result[-1] + x] ,the_list, [0])[1:]
[1, 3, 6, 10, 15]

Resources