Related
I am trying to implement insertion sort using python. Below is my code:
import numpy as np
N=int(input())
A=input().split()
#A=[int(x) for x in input().split()]
B_sorted=A.copy()
C= A.copy()
def inssort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while (j >=0 and key < arr[j]):
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
inssort(B_sorted)
for i in range(0,len(A)):
for j in range(0,len(A)):
if A[i]==B_sorted[j]:
C[i]=j+1
break
j=j+1
i=i+1
for x in B_sorted:
print (x, "",end="")
My code works for the following set of entries:
[9,8,7,...,2,1]
[20,19,...,12,11]
[20,19,...,11,10]
but it doesn't work for following
[10,9,8,...,2,1]
I don't understand what exactly is the issue here.
I tried to go to the detail by printing the output at every loop:
10 9 8 7 6 5 4 3 2 1
['10', '9', '8', '7', '6', '5', '4', '3', '2', '1']
['10', '8', '9', '7', '6', '5', '4', '3', '2', '1']
['10', '7', '8', '9', '6', '5', '4', '3', '2', '1']
['10', '6', '7', '8', '9', '5', '4', '3', '2', '1']
['10', '5', '6', '7', '8', '9', '4', '3', '2', '1']
['10', '4', '5', '6', '7', '8', '9', '3', '2', '1']
['10', '3', '4', '5', '6', '7', '8', '9', '2', '1']
['10', '2', '3', '4', '5', '6', '7', '8', '9', '1']
['1', '10', '2', '3', '4', '5', '6', '7', '8', '9']
Looks like for some reason at the first iteration j is not taking the value 0 for this particular sequence. As I mentioned before, it works perfectly for a lot of other sequences.
Kindly help.
n=10
fun=list(map(lambda x:[j for j in range(x)],n))
print(fun)
expected output is:
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# using map (map works on an iterable)
n=10
fun=lambda x: (range(x)) # remember this is a function (so call it)
fun=list(map(str, fun(n)))
print(fun)
# directly
n=10
fun=list(map(str, (range(n))))
print(fun)
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
Python docs for reference:
map(): https://docs.python.org/3/library/functions.html#map
range(): https://docs.python.org/3/library/functions.html#func-range
lambda(): https://docs.python.org/3/library/ast.html?highlight=lambda#ast.Lambda
I have a list
List = ['PK', 'K', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
I have another list that has,
Grade = ['K','4','8']
I would like to see elements previous to 'K' and next to '8' from List and add it to Grade.
Expected result :
Grade = ['K','4','8','PK','9']
this might work:
Grade = ['K','4','8']
Grade = Grade + [List[List.index(Grade[0]) - 1], List[List.index(Grade[-1]) + 1]]
# ['K', '4', '8', 'PK', '9']
get the index in your List and increase or decrease it by 1.
this will raise a ValueError if the first and last element of Grade are not in List.
Looks like you need.
lst = ['PK', 'K', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
Grade = ['K','4','8']
Grade = Grade + [lst[lst.index(Grade[0])-1], lst[lst.index(Grade[-1])+1]]
print(Grade) # --> ['K', '4', '8', 'PK', '9']
Grade.insert(Grade.index('8'), l[l.index('8')+1])
or this way for the previous item
Grade.insert(Grade.index('K'), l[l.index('K')-1])
it's best not to call your list "List", since that's an existing class in python
List = ['PK', 'K', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
Grade = ['K','4','8']
List[:List.index(Grade[0])]+ Grade + list(List[List.index(Grade[-1])+1])
#['PK', 'K', '4', '8', '9']
First off i am certain that such a basic thing has been asked before, but i could not find a post about it.
I have this piece of example data:
'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
And i want to print out every line (each line is one dictionary key-value pair) that has a list-value whose list contains any amount of items that is not 0 (in this case, every line except the 4th)
I just cant seem to figure out this seemingly simple thing - what i tried before was those two things:
for i in d.keys():
if "0" not in d[i]:
print(i, d[i])
This one shows only lists that do not contain 0 AT ALL - so the third line would not be shown, even though it contains non-0 values
for i in d.keys():
for j in d[i]:
if j is not "0":
print(i, d[i])
This one DOES show me what i want, but as you can tell, it prints every result way too often - one print for every list value that is not 0.
You can simply iterate over like
def all_zero(arr):
for i in arr:
if i != 0:
return False
else:
return True
You can call it on all the lists one by one.
Use a dictionary-comprehension:
d = {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']}
result = {k: v for k, v in d.items() if not all(x == '0' for x in v)}
# {'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
# '192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
# '192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6']}
The above code generates a new dictionary which omits all items where values are all zeros.
Now that you have a dictionary, you can easily do an iteration like so:
for k, v in result.items():
print(k, v)
Your bug is basically just a missing break:
for i in d.keys():
for j in d[i]:
if j != "0":
print(i, d[i])
break
However, for conciseness I would recommend you check out the any() function, which does exactly what you want: Return true if any of the elements of the iterable are true (when cast to booleans).
Eg:
for i in d.keys():
if any(j != "0" for j in d[i]):
print(i, d[i])
(The j is not "0" generator is only necessary because you have string values. For an int array, any(d[i]) would work.)
Even more "Pythonic" would be removing the need for a dictionary lookup:
for i, d_i in d.items():
if any(j != "0" for j in d_i):
print(i, d_i)
I like the other answers but I feel like you can get away with something like this as well:
for i in d.keys():
#If there are as many zeroes as there are elements in the list...
if d[i].count(0) == len(d[i]):
#...You might as well skip it :)
continue
print(d[i])
for i in d.keys():
all_zero = True
for j in d[i]:
if j is not "0":
all_zero = False
break
if not all_zero:
print(i, d[i])
This may work for almost every language :)
Have a look at how I could accomplish this.
d = {
'192.168.244.213': ['8', '4', '3', '1', '6', '5', '3', '2', '6', '5'],
'192.168.244.214': ['6', '8', '7', '6', '5', '4', '2', '7', '5', '5'],
'192.168.244.215': ['4', '10', '0', '8', '7', '0', '4', '3', '2', '6'],
'192.168.244.230': ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
}
for key in d.keys():
if all( item == '0' for item in d[key]):
pass
else:
print(key, d[key])
You should use all in this case, consider following example:
digits = ['0', '2', '0', '4', '7', '5', '0', '3', '2', '6']
zeros = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
print(all([k=='0' for k in digits])) #gives False
print(all([k=='0' for k in zeros])) #gives True
Please remember to deliver [k=='0' for k in ...] to all, as delivering list directly would give True for both digits and zeros, as both contain at least one non-empty str (str of length 1 or greater).
I know that you can swap 2 single indexes in Python
r = ['1', '2', '3', '4', '5', '6', '7', '8']
r[2], r[4] = r[4], r[2]
output:
['1', '2', '5', '4', '3', '6', '7', '8']
But why can't you swap 2 slices of indexes in python?
r = ['1', '2', '3', '4', '5', '6', '7', '8']
I want to swap the numbers 3 + 4 with 5 + 6 + 7 in r:
r[2:4], r[4:7] = r[4:7], r[2:4]
output:
['1', '2', '5', '6', '3', '4', '7', '8']
expected output:
['1', '2', '5', '6', '7', '3', '4', '8']
What did I wrong?
output:
The slicing is working as it should. You are replacing slices of different lengths. r[2:4] is two items, and r[4:7] is three items.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:4]
['3', '4']
>>> r[4:7]
['5', '6', '7']
So when ['3', '4'] is replaced, it can only fit ['5', '6'], and when ['5', '6', '7'] is replaced, it only gets ['3', '4']. So you have ['1', '2',, then the next two elements are the first two elements from ['5', '6', '7'] which is just ['5', '6', then the two elements from ['3', '4' go next, then the remaining '7', '8'].
If you want to replace the slices, you have to start slices at the right places and allocate an appropriate size in the array for each slice:
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
old index: 4 5 6 2 3
new index: 2 3 4 5 6
Think of this:
r[2:4], r[4:7] = r[4:7], r[2:4]
as similar to this:
original_r = list(r)
r[2:4] = original_r[4:7]
r[4:7] = original_r[2:4]
So, by the time it gets to the third line of that, the 4th element isn't what you think it is anymore... You replaced '3', '4' with '5', '6', '7', and now the [4:7] slice starts with that '7'.
>>> r = ['1', '2', '3', '4', '5', '6', '7', '8']
>>> r[2:5], r[5:7] = r[4:7], r[2:4]
>>> r
['1', '2', '5', '6', '7', '3', '4', '8']
In your code:
>>> r[2:4], r[4:7] = r[4:7], r[2:4]
You are assigning r[4:7] which have 3 elements to r[2:4] which have only 2.
In the code I posted:
>>> >>> r[2:5], r[5:7] = r[4:7], r[2:4]
r[4:7] which is ['5', '6', '7'], replaces
r[2:5] which is ['3', '4', '5']
r resulting in ['1', '2', '5', '6', '7', '6', '7', '8']
and then:
r[2:4] which was ['3', '4'], replaces
r[5:7] which is ['6', '7']
So final result being:
['1', '2', '5', '6', '7', '3', '4', '8']