Referencing python variable inside functions - python

I have the following python code to delete all the copies of a file in a certain directory keeping only one of them.
It works fine if i comment out the first four lines in the delete() function but if i don't it gives me a error that local variable list1 referenced before assignment. Also I tried using something called global but it didn't help me much as it gave error saying that it is NoneType.
Please help me i am just a intermediate beginner in Python.
list1 = []
list2 = []
def stripe(lis):
for i in range(len(lis)):
lis[0] = lis[0].strip()
def scan(pat):
pat = os.path.abspath(pat)
files = os.listdir(pat)
for file in files:
filepath = os.path.join(pat,file)
if os.path.isfile(filepath):
list1.append(file)
list2.append('{0}'.format(filepath))
elif os.path.isdir(filepath):
scan(filepath)
def delete():
list1_1 = stripe(list1)
list2_1 = stripe(list2)
list1 = list1_1
list2 = list2_1
length = len(list1)
#length = length - 1
i = 0
while i < length:
item = list1[0]
a = list1[0]
b = list2[0]
del list1[0]
del list2[0]
if item in list1:
try:
os.remove(list2[list1.index(item)])
#del list1[list1.index(item)]
#del list2[list1.index(item)]
except:
print('sorry',list1[0],'could not be deleted',sep = ' ')
print('wow')
i += 1
#list1.append(a)
#list2.append(b)

global looks like the right option for you, but if you say it gives error, use the way that comes to mind first. list1 and list2 can be the parameters of the delete() function.
Something like this:
def delete(list1, list2):
...
def foo():
list1 = []
list2 = []
...
delete(list1, list2)
Also, as I said, global is always an option. Here is an easy example:
list = []
def foo():
global list
list.append(1234)
def foo2():
global list
print(list)
foo()
foo2()
Output:
[1234]

Related

Enumerate list using recursion, python

I'm trying to enumerate the list using recursion and am having a hard time doing so.
If anyone can point me in the right direction that would be greatly appreciated! :)
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(ans)**strong text**
Try:
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
result += my_enumerate(items[1:], start_index + 1) # here
return result
The following is more concise:
def my_enumerate(items, start_index=0):
"""my enumerate"""
return [(start_index, items[0])] + my_enumerate(items[1:], start_index + 1) if items else []
As you are using recursion and you are declaring result = [] within a function so everytime it simply gets empty so you lose all previous results.
If you want exactly this to work there is also another way that by making the result as global if you wanted to use that list globally like below:
result = []
def my_enumerate(items, start_index=0):
"""my enumerate"""
global result
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(and)
But #CocompleteHippopotamus answer will work when you don't want to use a global keyword.

If-in statement testing for a list in nested lists not recognizing the first list is inside the second one when used in a function

The if-in statement should print 'test', but it will not. Whenever I try a similar idea outside of a function, it works perfectly, as in the example at the bottom. I can tell the problem is with the if in statement, but I don't understand why it doesn't work. Is there anything I can do to fix this?
class Pawn:
def __init__(self, num, pos, col, fmove):
self.num = num
self.pos = pos
self.col = col
self.fmove = fmove
w_pawn1 = Pawn(1, [1, 2], 'White', True)
def move(piece, typ):
if typ == 'pawn':
if piece.fmove == True:
posmove = [[piece.pos[0], int(piece.pos[1])+1],
[piece.pos[0], int(piece.pos[1])+2]]
Move = input('Where do you want to move?')
print(Move)
print(posmove)
if Move in posmove:
print('test')
piece.pos = move
else: pass
list1 = [1,3]
list2 = [[1,3],[1,4]]
if list1 in list2:
print('ok')
output:ok

Nested Lists- Python

I need to write the body of a Python method that does the following:
1)takes a list, where list[0] is a string and list[1] is either a list which looks the same or None
2)print every string of the list
I have to use the while loop and not use list comprehension or flatten.
def pick_cherries_iter(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!', None]]]]]
>>> pick_cherries_iter(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
_______________________
_______________________
_______________________
_______________________
while _________________:
_______________________
_______________________
_______________________
I know that for the example above I can print cheery1 if I print cherry_field[0] or cherry1 for cherry_field[1][0] or cherry2 for cherry_filed[1][1][0] etc, however I am not sure how to go through these elements using the while loop.
I think this should work for you. Please check it.
Using While Loop:
def pick_cherry(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!',None]]]]]
>>> pick_cherry(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
while field[1] != None:
temp = field[0]
print temp
field = field[1]
print field[0]
Using Flatten(and Recursion):
flatten_field = []
def pick_cherry(field):
if field[1] != None:
flatten_field.append(field[0])
pick_cherry(field[1])
else:
flatten_field.append(field[0])
def flatten_func(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!',None]]]]]
>>> flatten_func(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
pick_cherry(field)
for item in flatten_field:
print item
I would do this recursively because you have no way of knowing if an element is a list or not.
#!/usr/bin/python -E
cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!', None]]]]]
def print_list(field):
i = 0
list_length = len(field)
while i < list_length:
if field[i] is not None and type(field[i]) is not list:
print(field[i])
else:
if field[i] is not None:
print_list(field[i])
i += 1
if i < list_length and type(field[i]) is list:
print_list(field[i])
i += 1
def pick_cherries(field):
if type(field) is list:
print_list(field)
pick_cherries(cherry_field)

return longest word from a string

I need to define a function called "len_score" that returns the length of a word. Call the "best" function with the len_score function as a parameter.
Output I want to be:
print(best(len_score, names), "has the longest name.")
McJagger has the longest name.
My code is:
def len_score(name):
lst=[len(x) for x in name]
return lst
def best(lst1,lst2):
final=zip(lst1,lst2)
return max final
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score, names) == 'McJagger')
But I got error and not sure how to set condition on the list.
I think what you're trying to do is:
def len_score(name):
lst = [len(x) for x in name]
return lst
def best(func, lst):
func_lst = func(lst) # call the passed in function ON lst
return lst[func_lst.index(max(func_lst))]
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score, names) == 'McJagger')
You are almost there:
def len_score(name):
lst=[len(x) for x in name]
return lst
def best(lst1,lst2):
final=zip(lst1,lst2)
return max(final)
names = ["Ben", "April", "Zaber", "Alexis", "McJagger", "J.J.", "Madonna"]
print(best(len_score(names), names)[1])
print(best(len_score(names), names)[1] == 'McJagger')
Working code: https://py3.codeskulptor.org/#user302_Lx3nAppYJe_0.py

Sort a list with string and numbers

I need help to organize one list in python.
What I need is that:
I have a list like this: [10,50,20,'STRING',5], i need organize this list, without move the string, like this: [5,'STRING'10,20,50]. is possible do this?
Thanks!
I need to create a linked list to check if has intersection in two strings, i check this at 'def Intersecao', the output need to be Ordered, and if the intersection was empty, i need to print the string 'VAZIO'.
class No():
def __init__(self, valor = None, proximo = None):
self.valor = valor
self.proximo = proximo
def getValor(self):
return self.valor
def getProximo(self):
return self.proximo
def setProximo(self, novo_proximo):
self.proximo = novo_proximo
class lista():
def __init__(self, inicio = None):
self.inicio = inicio
def Inserir(self, valor):
novo_no = No(valor)
novo_no.setProximo(self.inicio)
self.inicio = novo_no
def Buscar(self, valor):
dados = self.inicio
while dados:
if dados.getValor() == valor:
return dados
else:
dados = dados.getProximo()
return None
def Intersecao (self, lista):
no = self.inicio
intersecao = []
while no != None:
if (not lista.Buscar(no.getValor())):
no = no.getProximo()
else:
if(no.getValor() == ''):
intersecao.append('VAZIO')
no = no.getProximo()
elif(no.getValor() in intersecao):
no = no.getProximo()
else:
intersecao.append(no.getValor())
no = no.getProximo()
return intersecao
def MostrarLista(self):
lista = []
dados = self.inicio
while dados:
lista.append(str(dados.getValor()))
dados = dados.getProximo()
print('->'.join(lista))
MyList = lista()
MySecondList = lista()
lista = []
lista2 = []
for i in range(40):
dado = input()
if i < 20:
lista.append(dado)
elif i >= 20:
lista2.append(dado)
for i in lista:
MyList.Inserir(i)
for i in lista2:
MySecondList.Inserir(i)
listaOrdenada = []
for elementos in sorted(MyList.Intersecao(MySecondList)):
print(elementos)
For first question, if it is list only, one way to do is (there might be better way though):
# original list
my_list = [10,50,20,'STRING',5]
# Creating temporary list with all numbers in sorted order and reverse
# reversed such that we use pop() which is efficient in time complexity
sorted_list = sorted([element for element in my_list if not isinstance(element, str)], reverse=True)
# new list to append accordingly
new_list = []
# for each element if it is string then in new list it has same position as in original list
# else if it was originally number then, we append the respective sorted number
for index, element in enumerate(my_list):
if isinstance(element, str):
new_list.append(element)
else:
new_list.append(sorted_list.pop())
new_list
Output:
[5, 10, 20, 'STRING', 50]
Or, it can be done with list comprehension which looks cleaner:
# Using list comprehension
my_list = [10,50,20,'STRING',5]
sorted_list = sorted([element for element in my_list if not isinstance(element, str)], reverse=True)
new_list = [element if isinstance(element, str) else sorted_list.pop() for index, element in enumerate(my_list)]
new_list
which gives same output.

Categories

Resources