I wanted to replace the items from listoflist = [[None, None, None]] with the output from
def _execute():
user_input = input("type in: ")
return user_input
without creating a new list
def insertdata(data): is doing that. its start with the first value and continues till the last value
def insertdata(data):
data_added = False
n = len(listoflist[0])
index = 0
while not data_added and index != n:
if listoflist[0][index] is None:
listoflist[0][index] = data
data_added = True
else:
index += 1
if index == n:
print("\n The list is full, No more elements will be added \n")
while True:
insertdata(_execute())
print(listoflist)
I want to extend the function to loop over a nested list with multiple rows.
what condition should the if statment have so it starts at the first row and execute the inner loop `?
def double_loop(data):
data_added_outer = False
index_outer = 0
n_out = len(listoflist)
# outer loop
while not data_added_outer and index_outer < n_out:
if: # what condition ?
#### inner loop ###############
data_added_inner = False
n_inner = len(listoflist[index_outer])
index_inner = 0
while not data_added_inner and index_inner != n_inner:
if listoflist[index_outer][index_inner] is None:
listoflist[index_outer][index_inner] = data
data_added = True
else:
index_inner += 1
if index_inner == n_inner:
print("\n The list is full, No more elements will be added \n")
####### inner ############################################################
else:
index_outer += 1
if index_outer == n_out:
print("\n The list is full, No more elements will be added \n")
Instead of replacing the data, the elegant approach in Python is to create new data, using comprehensions:
def with_nones_replaced(grid, replacement):
return [
[
replacement if value is None else value
for value in row
]
for row in grid
]
As far as I have understood, the job of your function is simply to replace the None objects in a 2D-List with the data parameter passed to the function. I find a for-loop approach much more cleaner, and pythonic in this case.
def changedata(arr, data):
for item in arr:
for x in range(len(item)):
if item[x] is None:
item[x] = data
You can also use the map function to simplify the code:
def changedata(arr, data):
for i in range(len(arr)):
arr[i] = list(map(lambda x: data if x is None else x, arr[i]))
If the data is coming from a function, you can still use this paradigm by calling
_execute() once, storing it in a variable, and then passing it to changedata()
data = _execute()
changedata(listoflist, data)
print(listoflist)
Related
strs = ["cir","car"]
#strs = ["flower","flow","flight"]
def get_min_str(lst):
return min(lst, key=len)
str1 = get_min_str(strs)
lens = len(strs)
x = ""
mlen = len(str1)
if(lens == 1):
print(strs[0])
for i in range(0, mlen):
for j in range(0, lens-1):
if( strs[j][i] == strs[j+1][i] ):
if(j == lens-2):
x = x + strs[j][i]
print(strs[j][i])
else:
break
print(strs[j][i] == strs[j+1][i])
print(x)
So in order to find the longest common prefix, I have used two loops. To loop over the values. But in the example, strs = ["cir","car"]. I should the value x = "c" but I stead get the value "cr", since I have used the break function. The function should have stopped at c. Why isn't it?Why do I get the value "cr"your text
Since you have two nested loops, the break keyword only exits the inner loop. Then, the third letter matches, so r is added to x. To fix this, set a variable when you should exit the outer loop and check it before each iteration.
Edit: also, for readability's sake, you may want to explore the enumerate() function, which converts an iterable (like a string) into an iterable of tuples of the form (index, value), so your code could look like:
should_break = False
for letter_index, current_character in enumerate(str1):
if should_break:
break
for str_index in range(0, lens):
if strs[str_index][letter_index] != current_character:
should_break = True # set break condition for outer loop
break # break from inner loop
else: # executed when the for loop doesn't break
x += current_character
Here is the code:
count_1 = 0
count_0 = 0
list = ('001111011011','000110001010','011010111111')`
for i in list:
index = 0
y = i[index]
if y == "1":
count_1 = count_1 + 1
if y == "0":
count_0 = count_0 + 1
if count_1 > count_0:
for i in list:
final_after_1 = []
if i[0] == "1":
final_after_1.append(i)
formatted = (','.join(final_after_1))
if count_0 > count_1:
for i in list:
final_after_1 = []
if i[0] == "0":
final_after_1.append(i)
formatted = (','.join(final_after_1))
if count_0 == count_1:
for i in list:
final_after_1 = []
if i[0] == "1":
final_after_1.append(i)
print(final_after_1)
formatted = (','.join(final_after_1))
print(formatted)
(Apologies in advance if this question is worded badly, this is my first time asking a question).
This piece of code is working fine except for this one issue. It is designed to identify the first index of each 12-digit number in the list, and then work out if a 1 or 0 is more common in this position. It then selects all the numbers with the more common number in the first position and adds them to a list. I want to print this list at the end of the program.
I have defined a variable (called formatted) to be equal to a list of various numbers. When I print it out within the loop I have defined it in, it prints all the numbers that should be in the list, like this:
When I print it outside of the loop as in the code above it returns only the final number:
011010111111
Whereas printing it inside the loop like this:
if count_0 > count_1:
for i in list:
final_after_1 = []
if i[0] == "0":
final_after_1.append(i)
formatted = (','.join(final_after_1))
print(formatted)
does return this full desired list:
001111011011
000110001010
011010111111
Any ideas why this is happening?
Within you loop(s) the value of formatted is updated for each iteration. After the last iteration it is no longer updated and that last value is the output of the last print statement.
A simpler example:
for x in range(100):
pass//looping over, x is 0..99
print(x)
This will print out 99, the last value held by the variable "x".
Problably your code is updateing the variable for each iteration so in a for loop you need to append the values and not overwrite them, for example:
a = 0
b = 0
for i in 10:
a = 1
b = b + 1 # using the last value
print(a) # 1
print(b) # 9
First of all you shouldn't use "list" as a variable name because is a built-in name to instanciate lists or arrays. In second your code is repeated 3 times just for count a bit, let me show a better way with list compreenssions:
l = ('001111011011','000110001010','011010111111')
first_elements = list()
for x in l:
v = x[0] # first element
first_elements.append(int(v))
# [0,0,0]
count_0 = first_elements.count(0)
# count_0 = 3
count_1 = first_elements.count(1)
# count_1 = 0
Using list compreenssion
first_elements = [int(x[0]) for x in l]
# [0,0,0]
References: list compreenssions, list, list.count
I have to do the following:
Define a function called isSymmetricalVec that takes a list of elements, checks if each element in a list is palindrome, then returns their results in a list. For example, given ["1441", "Apple", "radar", "232", "plane"] the function returns [TRUE, FALSE, TRUE, TRUE, FALSE].
I wrote the following code but I'm stuck at the point where I cannot return the result in a list.
def isSymmetricalVec(myList):
for myString in myList:
myList = []
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
print(bool(1))
else:
print(bool(0))
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
isSymmetricalVec(myList)
My function returns the following but the result is not in a list format:
True
False
True
False
How can I modify my code to return a result in a list format?
You function should return value instead of printing it.
Created an empty list new_list and appended result to it.
def isSymmetricalVec(myList):
new_lst = []
for myString in myList:
mid = (len(myString) - 1) // 2
start = 0
last = len(myString) - 1
flag = 0
while (start < mid):
if (myString[start] == myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
new_lst.append(True)
else:
new_lst.append(False)
return new_lst
# Enter a list of strings to check whether it is symmetrical or not
Your function is actually not returning anything. What you see are only being printed and not returned.
You would want to keep each answer in a list like this.
def isSymmetricalVec(myList):
list_of_answers = []
for myString in myList:
...
while(start<mid):
...
if flag == 0:
print(bool(1))
list_of_answers.append(True)
else:
print(bool(0))
list_of_answers.append(False)
return list_of_answers
This way your answers are printed and returned.
Finally, you would need a variable to hold the returned list.
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
list_of_answers = isSymmetricalVec(myList)
def isSymmetricalVec(myString):
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
return True
else:
return False
test = ["1221", "madam", "hello world"]
final = [isSymmetricalVec(i) for i in test]
print(final)
I rewrote the code a bit and this would be my solution. It retains the original functionality and is stylish as well as efficient. It also makes the original function more flexible and makes it easily migratable.
Your function doesn't return anything, just printing values.
There is a good way to shorten your algorithm with python slices. Also this function returns list of boolean objects.
from math import ceil, floor
def isSymmetricalVec(myList):
list_of_answers = []
for string in myList:
strLength = len(string)
#There is a string palindrome check
if string[:floor(strLength//2)] == string[ceil(strLength/2):][::-1]:
toAppend = True
else:
toAppend = False
list_of_answers.append(toAppend)
return list_of_answers
It is worth adding that it's better to use True and False instead of bool(1) and bool(0).
An example:
>>> isSymmetricalVec(['11211', 'AbbA', '12f23'])
>>> [True, True, False]
I'm a Python newbie and trying to write code that checks if a nested list has a valid set of numbers. Each row and each column have to be valid. I have written a function called check_sequence which validates if a list has a valid set of numbers. How would I call that function from another to check to see if the row is valid? So for example, I need something like this for check_rows:
check_sequence(list):
checks if list is valid
check_rows(list):
For each of the rows in the nested list call check_sequence
Here is my code for check_sequence:
def check_sequence(mylist):
pos = 0
sequence_counter = 1
while pos < len(mylist):
print "The pos is: " + " " + str(pos)
print "The sequence_counter is:" + " " + str(sequence_counter)
for number in mylist:
print "The number is:" + " " + str(number)
if number == sequence_counter:
sequence_counter = sequence_counter + 1
pos = pos + 1
break
else:
# if list is at the last position on the last item
if sequence_counter not in mylist:
print "The pos is:" + " " + str(pos) + " and the last position is:" + " " + str(mylist[len(mylist) - 1])
print "False"
return False
print "True"
return True
So I'd call the main method like below:
check_square([[1, 2, 3],
[2, 3, 1],
[3, 1, 2]])
def check_square(list):
if check_rows() and check_columns() == True:
return True
else:
return False
Here's a solution that'll work for any arbitrary 2D list.
l = [[1,2,3],[1,2],[1,4,5,6,7]]
try:
if len([1 for x in reduce(lambda x, y :x + y, l) if type(x) != type(0)]) > 0:
raise Exception
catch Exception:
pass # error, do something
The intuition is to flatten the list and then successively check if its type is int.
Given the nested list is row oriented (the rows are the lowest dimension), you can simply use:
check_rows(list):
return all(check_sequence(sublist) for sublist in list)
Here we thus use the all(..) builtin: it evaluates to True if and only if the truthiness of all elements the generator (boldface part) is True, otherwise the result is False. So from the moment one of the rows is not valid, the matrix is not valid.
If on the other hand the nested list is column oriented (the columns are the lowest dimension), we will first need to do a transpose using zip:
check_rows(list):
return all(check_sequence(list(sublist)) for sublist in zip(*list))
The zip(*..) transposes the list and we use list(..) to make sure that check_sequence(..) is still working with lists (if any iterable is sufficient, the list(..) part can be omitted.
Are you looking for an iterative for loop?
check_sequence(list):
#your check here
check_rows(list):
for row in list:
if not check_sequence(row):
return False
return True
You have to separate in two function, and think the first one will return the complete check for each value of the other:
def check_sequence(lis):
ret = True
for row in lis:
ret = ret and check_rows(row)
return ret
def check_rows(row):
ret = True
for elem in row:
pass #do your checking
return ret
a concrete example could be:
l = [[1,2,3],[1,2],[1,4,5,6,7]]
def check_sequence(lis):
ret = True
for row in lis:
ret = ret and check_rows(row)
return ret
def check_rows(row):
return 1 in row #ask if 1 belongs to the list
check_sequence(l) ---> True
check_sequence([[1],[2,3]]) ---> False
I am developing a procedure add_to_index, that takes 3 inputs:
an index: [[,[url1,url2,...]],...]
a keyword: String
a url: String
If the keyword is already in the index, url is added to the list of urls associated with that keyword.
If the keyword is not in the index, a new element is to the index:
[keyword,[url]]
CODE
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
count += 1
if(lists[0]==keyword):
index[count][1].append(url)
if(flag ==0):
index.append([keyword,url])
#calling the function below
add_to_index(index,'google','http://google.com')
print index
output -> [['google', 'http://google.com']]
add_to_index(index,'computing','http://acm.org')
print index
output -> [['google', 'http://google.com'], ['computing', 'http://acm.org']]
add_to_index(index,'google','http://gmail.com')
print index
error->
index[count][1].append(url)
AttributeError: 'str' object has no attribute 'append'
Expected output:
[['google', ['http://google.com', 'http://gmail.com']],
['computing', ['http://acm.org']]]
You have done three mistakes, Firstly you have not used the flag and secondly you are adding the url as a string. And finally as Kaivosuketaja has mentioned in the comment, count should be incremented in the end. It can be done otherwise as
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if(lists[0]==keyword):
flag = 1
index[count][1].append(url)
count += 1
if(flag ==0):
index.append([keyword,[url]])
# Take note of append away here
#calling the function below
add_to_index(index,'google','http://google.com')
print index
add_to_index(index,'computing','http://acm.org')
print index
add_to_index(index,'google','http://gmail.com')
print index
The output now is
[['google', ['http://google.com']]]
[['google', ['http://google.com']], ['computing', ['http://acm.org']]]
[['google', ['http://google.com', 'http://gmail.com']], ['computing', ['http://acm.org']]]
I think this is what you want:
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if lists[0] == keyword:
lists[1].append(url)
flag = 1
count += 1
if flag == 0:
index.append([keyword, [url]])
#calling the function below
add_to_index(index,'google','http://google.com')
print index
I will suggest the use of dictionaries for this:
index = {}
def add_to_index(index, keyword, url):
if keyword not in index:
index[keyword] = [url]
else:
index[keyword].append(url)
>>> add_to_index(index,'computing','http://acm.org')
>>> add_to_index(index,'google','http://gmail.com')
>>> add_to_index(index,'google','http://gmail.com')
>>> index
{'computing': ['http://acm.org'], 'google': ['http://gmail.com', 'http://gmail.com']}
You could even make index a non global variable by implementing a simple class(ofcourse, this is possible with nested lists too):
class Index(object):
def __init__(self):
self.index = {}
def add_to_index(self, keyword, url):
if keyword not in index:
self.index[keyword] = [url]
else:
self.index[keyword].append(url)
First, you're trying to append to a string that is inside of the list you want to append to. Then, you forgot to say flag = 1 when you've found the keyword. Try the following:
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if(lists[0]==keyword):
index[count][1].append(url)
flag = 1
count += 1
if(flag ==0):
index.append([keyword,url])
#calling the function below
add_to_index(index,'google','http://google.com')
add_to_index(index,'computing','http://acm.org')
add_to_index(index,'google','http://gmail.com')
print index
I think you'd be much better off using a defaultdict, though. It automatically searches for a keyword and adds the item to the existing keyword, or if it isn't found, creates a new keyword.
You could simplify things a little by getting rid of the flag and count variables.
index = []
def add_to_index(index, keyword, url):
for e in index:
if e[0] == keyword:
e[1].append(url)
return
else:
index.append([keyword,[url]])