I am a Network Engineer trying to learn Python programming as a job requirement.
I wrote this code below to
# Funtion to chop the first and last item in the list
def chop(t):
t.pop(0) and t.pop(len(t)-1)
return t
When I run the function on the list t and assign it to a variable a. a gets the remainder of the list after the function was executed and a becomes a new list.This works perfect.
>>> t = ['a', 'b', 'c', 'd', 'e' ,'f','g','h','i','j','k','l']
>>> a=chop(t)
>>> a
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
>>>
Later when i try it works well but the value of a also changes to the output of print chop(t) whereas I did not run the variable a through the function chop(t). Can someone explain why does this happen?
>>> print chop(t)
['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> a
['c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
Regards
Umesh
To save unmodified list t, create copy of it by a = t[:], and test chop on list a
>>> t = ['a', 'b', 'c', 'd', 'e' ,'f','g','h','i','j','k','l']
>>> a=t[:]
>>> a.pop(0)
'a'
>>> a
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
>>> t
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
>>>
When you call chop(t) , t is being passed by reference. So when you do the operation "t.pop(0) and t.pop(len(t)-1)" , it is being done on the original object and not a copy.
Because of the above , the below is true as well
>>> t = ['a', 'b', 'c', 'd', 'e' ,'f','g','h','i','j','k','l']
>>> chop(t)
>>> t
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']
>>>
t = ['a', 'b', 'c', 'd', 'e' ,'f','g','h','i','j','k','l']
def chop(t):
t.pop(0) and t.pop(len(t)-1)
return t
a=chop(t)
In python, Assignment never copies data.
By doing a=chop(t) is like Simply storing the reference to the function in a variable.
Hence, every time we call a we get chop() function executed.
Related
with open(sys.argv[1]) as f:
lst = list(f.readline().strip())
sortedLst = sorted(lst, key = lambda x: (x.lower(), x.swapcase()))
print(lst)
print(sortedLst)
The word I am using as an example is 'ThatCcer'.
My outputs are ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r'] for lst and my outputs are ['a', 'c', 'C', 'e', 'h', 'r', 't', 'T'] for sortedLst.
This is exactly what I am going for - to sort a word in alphabetical order with lower case letters taking precedence over upper case.
What I am trying to achieve is to match other 8-letter inputs by sorting them in the exact way that I have sorted ThatCcher. How would I go about achieving this?
EDIT: I am being told the question is unclear - my apologies but it is a bit difficult to explain so I will try again.
By sorting ThatCcer to become acCehrtT, lst[0] ('T') took the position of sortedLst[7], lst[1] ('h') took the position of sortedLst[4], and so on...
This is the history I want to record and so that given any other string can copy the steps that 'ThatCcer' took, for example: s = ['h', 'o', 'w', 'e', 'v', 'e', 'r', 's'] I want s[0] to to take its' position in sortedS[7], just like ThatCcer did.
I hope this made it a little clearer!
IIUC, you want to achieve a behavior similar to that of numpy.argsort.
You can sort a range based on your criteria, and use it to reindex any string:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
idx = list(range(len(lst)))
sorted_idx = sorted(idx, key=lambda x: (lst[x].lower(), lst[x].swapcase()))
# [2, 5, 4, 6, 1, 7, 3, 0]
# now use the index to sort
[lst[i] for i in sorted_idx]
# ['a', 'c', 'C', 'e', 'h', 'r', 't', 'T']
# keep the same order on another string
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
[lst2[i] for i in sorted_idx]
# ['c', 'f', 'e', 'g', 'b', 'h', 'd', 'a']
Another approach using zip:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
list(zip(*sorted(zip(lst, lst2), key=lambda x: (x[0].lower(), x[0].swapcase()))))
# or as individual lists
# (lst_sorted, lst2_sorted) = list(zip(*sorted(zip(lst, lst2),
# key=lambda x: # (x[0].lower(), x[0].swapcase()))))
output:
[('a', 'c', 'C', 'e', 'h', 'r', 't', 'T'),
('c', 'f', 'e', 'g', 'b', 'h', 'd', 'a')]
Sort the enumerated string on the string characters, then separate the (sorted) indices and characters; use operator.itemgetter to create a callable that you can re-use.
import operator
def f(thing):
s_lst = sorted(enumerate(thing),key = lambda x: (x[1].lower(), x[1].swapcase()))
argsort = operator.itemgetter(*[x[0] for x in s_lst])
s_lst = [x[1] for x in s_lst]
return s_lst,argsort
>>> s_lst, argsort = f('ThatCcerCTaa')
>>> s_lst
['a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T']
>>> argsort('ThatCcerCTaa')
('a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T')
>>> argsort
operator.itemgetter(2, 10, 11, 5, 4, 8, 6, 1, 7, 3, 0, 9)
>>>
I want to create all possible permutations for an array in which each element can only occur once, with constraints on the element array index position.
ID = ["A","B","C","D","E","F","G","H","I","J"]
I want to create all possible permutations of the original_array, however the positions of each element are restricted to index positions given by:
ID = ["A","B","C","D","E","F","G","H","I","J"]
Index_Options=[]
for i in range(len(ID)):
List1=[]
distance=3
value = i - distance
for j in range((int(distance)*2)):
if value < 0 or value > len(ID):
print("Disregard") #Outside acceptable distance range
else:
List1.append(value)
value=value+1
Index_Options.append(List1)
print(Index_Options)
#Index_Options gives the possible index positions for each element. ie "A" can occur in only index positions 0,1,2, "B" can occur in only index positions 0,1,2,3 ect.
I'm just struggling on how to then use this information to create all the output permutations.
Any help would be appreciated
You can use a recursive generator function to build the combinations. Instead of generating all possible permutations from ID and then filtering based on Index_Options, it is much more efficient to produce a cartesian product of ID by directly traversing Index_Options:
ID = ["A","B","C","D","E","F","G","H","I","J"]
def combos(d, c = [], s = []):
if not d:
yield c
else:
for i in filter(lambda x:x not in s and x < len(ID), d[0]):
yield from combos(d[1:], c=c+[ID[i]], s=s+[i])
print(list(combos(Index_Options)))
Output (first ten combinations produced):
[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'I', 'H', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'I', 'J', 'H'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'J', 'H', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'J', 'I', 'H'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G', 'I', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'G', 'J', 'I'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'I', 'G', 'J'], ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'I', 'J', 'G']]
You can use itertools.permutations to create all the possible permutations and then create new list with a check if all the letters are in the correct position
permutations = [p for p in itertools.permutations(ID, len(ID)) if all(i in Index_Options[ID.index(x)] for i, x in enumerate(p))]
I saw this code in w3resource:
C = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']
def list_slice(S, step):
return [S[i::step] for i in range(step)]
print(list_slice(C,3))
Output :[['a', 'd', 'g', 'j', 'm'], ['b', 'e', 'h', 'k', 'n'], ['c', 'f', 'i', 'l']]
I tried it without list comprehension and a function:
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']
step = int(input("Step of every element: "))
for i in range(step):
print(letters[i::step])
Output:
['a', 'd', 'g', 'j', 'm']
['b', 'e', 'h', 'k', 'n']
['c', 'f', 'i', 'l']
is it possible to make my output like this [['a', 'd', 'g', 'j', 'm'], ['b', 'e', 'h', 'k', 'n'], ['c', 'f', 'i', 'l']] without using list comprehension and without making another variable with an empty list?
not a list comprehension solution, but since you want an element having certain distance/step in the list to be in the same list, then you can see that those element index share single property altogether which have the same remainder to the step value, using this approach you can save those value for that index remainder in a key-value pair of dict and in result you can take the values which are nonempty.
C = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']
def func(lis, slic):
res = {i:[] for i in range(len(lis)//slic)}
for i in range(len(lis)):
res[i%slic].append(lis[i])
return [i for i in res.values() if i!=[]]
print(func(C, 3))
# Output :[['a', 'd', 'g', 'j', 'm'], ['b', 'e', 'h', 'k', 'n'], ['c', 'f', 'i', 'l']]
I'm beginner to programming and I'm new here, so hello!
I'm having a problem with nodes order in networkX.
This code:
letters = []
G = nx.Graph()
for i in range(nodesNum):
letter = ascii_lowercase[i]
letters.append(letter)
print letters
G.add_nodes_from(letters)
print "G.nodes = ", (G.nodes())
returns this:
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
G.nodes = ['a', 'c', 'b', 'e', 'd', 'g', 'f', 'i', 'h', 'j']
While I would like to have it in normal (alphabetical) order.
Could anyone tell me what am I doing wrong?
The order is important to me, as later I'm asking user to tell me where the edges are.
Thanks in advance!
You can sort the nodes on output like this
print "G.nodes = ", sorted(G.nodes())
or similarly you can sort the edges like
print "G.edges = ", sorted(G.edges())
Aric's solution would do fine if you want to use this for printing only. However if you are going to use adjacent matrix for calculations and you want consistent matrices in different runs, you should do:
letters = []
G = nx.OrderedGraph()
for i in range(10):
letter = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'][i]
letters.append(letter)
print (letters)
G.add_nodes_from(letters)
print ("G.nodes = ", (G.nodes()))
which returns
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
G.nodes = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
I'm using python to try and remove items that intersection from another list. So below is what I have.
letter = ['a', 'a', 'i', 'd', 'e', 'i', 'a', 'b', 'b', 'c', 'o', 'g', 'a', 'f', 'f', 'i', 'g', 'i' ]
cons = ['b','c','d', 'f', 'g']
and what I want is to remove any letter in the cons list from the letter list but preserve everything else. So below is what I want to get.
letter = ['a', 'a', 'i', 'e', 'i', 'a', 'o', 'a', i', 'i' ]
Below is what I have tried so far but it's not working.
for i in letter[:]:
if i in cons:
letter.remove(i)
cons.remove(i)
and...
list(set(x) - set(y))
I just want to remove the intersection of the lists and keep the duplicates from the first list that are not in the second list. Everything I've tried so far has removed those duplicates from the first list that I want to keep. Any help is greatly appreciated!
>>> letter = ['a', 'a', 'i', 'd', 'e', 'i', 'a', 'b', 'b', 'c', 'o', 'g', 'a', 'f', 'f', 'i', 'g', 'i' ]
>>> cons = ['b','c','d', 'f', 'g']
>>> [x for x in letter if x not in cons]
['a', 'a', 'i', 'e', 'i', 'a', 'o', 'a', 'i', 'i']
a simple list comprehension will do the trick?
EDIT:
As ShadowRanger said, it would improve performance (mostly for larger data sets than these) to convert cons to a set:
cons = set(cons)
then to go into the list comp. This is better because sets are hashed and makes getting items/checking for items in it way faster
A list comprehension is better, but your original code works if we just remove one line:
>>> letter = ['a', 'a', 'i', 'd', 'e', 'i', 'a', 'b', 'b', 'c', 'o', 'g', 'a', 'f', 'f', 'i', 'g', 'i' ]
>>> cons = ['b','c','d', 'f', 'g']
>>> for i in letter[:]:
... if i in cons:
... letter.remove(i)
...
>>> letter
['a', 'a', 'i', 'e', 'i', 'a', 'o', 'a', 'i', 'i']