Python items in a list still a list? - python

I'm trying to create a short script where 5 random numbers from an available list are selected and then each one is displayed. The problem I'm having is that the list to which I'm appending the results returns a list as well, not integers or strings. Here's the code:
def randomStar(self):
choice = [5,4,3]
probability = [0.1, 0.2, 0.7]
star = random.choices(choice, probability)
return star
multi = []
characters = []
for x in range(5):
star = randomStar(x)
multi.append(star)
x += 1
for star in multi:
characters.append(star)
print (characters)
print (multi)
Both multi and characters lists return:
['[3]', '[3]', '[3]', '[5]', '[3]']
So when I try to iterate through "Multi" list I still get lists. How can I get the values only? Or is the way I'm appending the numbers to the list incorrect?
Thanks.

They are lists because random.choices returns "a k sized list of elements".
Since there is only one element in the list, and this is what you are trying to return, you just want to write return star[0].

Related

Finding every possible list made by removing the first element from either of two lists and appending to the new list

I have two lists of ints, a and b, which do not necessarily have the same length. I would like to create new lists from these by removing either the first element of a, or the first element of b, and appending it to the new list, repeating this step until both a and b are empty. At each step in this process, the number of possible lists grows exponentially, and I'd like to know how to generate every list that is possible to create in this way.
So far, I've only managed to work out that the number of possible lists is equal to sum((2**i for i in range(len(a) + len(b)))). I have no idea how to proceed with this, and would appreciate any pointers.
For information, my end goal is to work out the sum of the differences between consecutive elements for each list, and find the minimum of these.
I think this can be achieved by using recursion. Some code.
permutation = [0]*10 # size of this list has to be equal to lenth of list1 + length of list2. (you can have 4 as the size of the list).
def task(list1,list2,index):
if len(list1)==0 and len(list2)==0: # if length of both the list is 0, we print the
print(permutation) # permutation list
return
if len(list1)>0:
permutation[index] = list1[0]
modified_list1 = list1[:] # Since lists in python are passed by reference, I am making a copy of the list
modified_list1.pop(0) # Removing the first element
task(modified_list1,list2,index+1) #and calling the function again using the modified list.
if len(list2)>0:
permutation[index] = list2[0]
modified_list2 = list2[:]
modified_list2.pop(0)
task(list1,modified_list2,index+1)
if __name__=="__main__":
list1 = [1]
list2 = [4,5,6]
task(list1,list2,0)
Recursive solutions can be a little tricky to understand, I will encourage you
to take a copy and pen and try simulating it for small input, you will
understand how things are working.
For your next task, when we are printing the permutation list, you can compute the differences of the adjacent numbers and store your result in any way you want.

How can I improve my python code to sort a list of numbers into groups?

I'm writing a code which takes a list of numbers, some of which are very close or equal to other elements of the list, for example [0.1,0.101,0.2,0.499,0.5], then returns a smaller list of the main numbers the elements of this list fall close to, so in this case [0.1005,0.2,0.4995].
At the moment my code would return the first number from each category from the list, so here it returns [0.1,0.2,0.499], but I need more accuracy.
Here's my current code:
def listsort(x):
deletelist = []
for i in range(len(x)):
for j in range(i+1,len(x)):
if abs(x[i]-x[j])<1e-5:
deletelist.append(x[j])
for j in deletelist:
x.remove(j)
return x

Using a for loop to calculate the average

Hi I'm sort of new to programming and I would really appreciate some help with this problem.
I have a list of scores and I would like to create a function which divides each individual score by the calculated average of the whole list. The function should accept a list of scores as an argument and return a list with the modified scores.
Also, it should make use of a for loop and a return statement.
Here is a brief example of the list of scores I have:
13
22
33
42
25
(there are over 500 scores)
tbh, the wording of your question was a little confusing, but here's what you would do.
def scoreAvg(scores):
scoresSum = sum(scores)
scoresSum /= len(scores)
newScores = []
for i in scores:
i /= scoresSum
newScores.append(i)
return newScores
print(scoreAvg([13,22,33,42,25]))
You said you were pretty new to python, so I'll give you a rundown of what's happening here. Input 'scores' is a list containing our set of example scores (remember to enclose the input in square brackets). We find the sum of that list with sum() and the length with len(). We then begin a for loop to loop through the elements of scores, and divide each element by the avg, then append that value to a list we created earlier to hold the new scores. Now all we have to do is return that list with return newScores !
Hope I could help.
You can try the following code.
from __future__ import division #For decimal division.
''' Function (func) '''
def func(lst):
new_list = [] #Define an empty new list.
for i in range(len(lst)):
new_list += [ lst[i]*len(lst) / sum(lst) ]
return new_list
mylist = [13, 22, 33, 42, 25] #List you wish to enter.
mod_list = func(lst = mylist) #Modified list.
print mod_list #Prints output (mod_list).
>>>[0.48148148148148145, 0.8148148148148148, 1.2222222222222223, 1.5555555555555556, 0.9259259259259259]
In the above code, each element of new_list is element of input list (lst=mylist) divided by average of input list. One can obtain average by using the following: average = sum of input list / number of elements in input list. In python, the function len() gives you the number of items of an object (e.g. list). The function sum() gives you the sum elements of an object.
I hope this was helpful. Let me know if you have any questions. =)

Simple Python Assistance

two fixes:, main should sort the returned list, and the for loop should print all numbers on one line.
This is the question I am answering, Thought I got it all but the two errors I have explained above need help:
In main, generate a random integer that is greater than 5 and less than 13. print this number on its own line.
Call the makelist function with the random integer as sole argument.
Make an empty list inside the makelist function.
Use a loop to append to the list a number of elements equal to the random integer argument. All new list elements must be random integers ranging from 1 to 100, inclusive. Duplicates are okay.
Return the list to main.
Back in main, catch the returned list and sort it.
Finally, use a for loop to display the sorted list elements, all on one line, separated by single spaces.
List size will be 7
Here is the sorted list:
8 28 35 41 51 62 72
ANOTHER SAMPLE OUTPUT
List size will be 10
Here is the sorted list:
3 3 9 20 36 43 48 50 81 93
Any help with my code is very much appreciated. Im a beginner and have tried tutorials.
Here is my code
import random
def main():
random_int = random.randint(6, 12)
print (random_int)
elements = makelist(random_int)
for n in sorted(elements):
print (n,)
def makelist(random_int):
number_list = []
for count in range(random_int):
number_list.append(random.randint(1, 101))
return number_list
main()
print (n,) if you want to print your items like your samples output, Your comma placement is where the problem lies. You see, parenthesis in python are used both for enclosing mathematical / logical expressions and for tuples. What happens if you want a 1-item tuple? (n) is the same as n. To solve that, python understands (n,)as a tuple.
So to print your items like you want, use:
for n in sorted(elements):
print (n),
print() # This last one is only to go down a line
# for any further prints
Edit: also, if you want a random_intbetween 1 and 100, use random.randint(1, 100), not 101
I would sort the list in the makelist function. In addition to this, you should remove the comma from print (n,). Otherwise your code pretty much solves the problem. Just be more specific with your question next time.
Edit: Calling each print() on each element on the list will print each element on a newline (Vertically). Since you needed to get rid of the commas, ' '.join(map(str, sorted(elements)) will convert the list to a string, with each element separated by an empty space.
import random
def main():
random_int = random.randint(6, 12)
print ("The list size will be %d" %random_int)
elements = makelist(random_int)
print("This sorted list is %s" %' '.join(map(str, sorted(elements))) )
def makelist(random_int):
number_list = []
for count in range(random_int):
number_list.append(random.randint(1, 100))
return number_list
Do it like this
import random
def main():
random_int = random.randint(6, 12)
print ('List size will be %d' % random_int)
elements = makelist(random_int)
print('Here is the sorted list:')
print( ' '.join(map(str, sorted(elements))) )
def makelist(random_int):
number_list = []
for count in range(random_int):
number_list.append(random.randint(1, 100))
return number_list
main()
The line of interest is
print( ' '.join(map(str, sorted(elements))) )
Which does a few things.
sorted(elements)
Return a sorted copy of the list.
map(str, sorted(elements))
Map (convert) the integer elements to strings. This just calls str on each element in the list. Its needed because join requires an iterable of strings.
' '.join(map(str, sorted(elements)))
This funny looking syntax will create one long string out of all the values. It will use ' ' (space character) as the value between each element and will join all the elements which have been sorted and converted to strings into one long string which can be printed.

Loop in a list (Python v3) beginner

I am stuck in making a loop that will eliminate the values(from the alist) that are below average.
Thanks for the help.
a=input("Enter a list of values separated by a coma : ")
alist=eval(a)
print("the list is : ",alist)
average = sum(alist)/len(alist)
print("the average is : ",average)
for i in alist:
if alist[i]<average:
alist.remove[i]
You are almost there. Instead of removing elements, select elements you want to retain instead:
alist = [a for a in alist if a>=average]
Your mistake here is that for i in alist: is iterating over list elements themselves, not indexes, so alist[i] is throwing an error (or returning nonsense).
For the "loop" you can use a filter and a lambda function.
above_average = list(filter(lambda x: x >= average, alist))
For the rest of your code, I suggest you clean it up to something which is safer (use of eval is very bad)
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
alist = list(ast.literal_eval(user_string)))
So, in all, I would write your code as something like this:
import ast
user_string = raw_input('input a list of numbers separated by a commas: ')
numbers = list(ast.literal_eval(user_string)))
average = sum(numbers)/len(numbers)
print('The numbers: {}'.format(numbers))
print('The average: {}'.format(average))
above_average = list(filter(lambda x: x >= average, numbers))
# now do what you want with the above_average numbers.
Other answers tell you how to do it. I'll tell you why it doesn't work:
You iterate over the list and, at the same time, modify it.
This leads to items being missed during the iteration.
Why?
Internally, the iteration works via an index to the list. So it is the same as doing
idx = 0
while True:
try:
i = alist[idx]
except IndexError:
break
idx += 1
if alist[i] < average:
alist.remove(i)
What happens if you are at the element #3, go to the next one and then remove #3? Right, the indexes of the remaining ones move down and you are pointing to the one which formerly was #5. The old #4 is skipped at this test.
(BTW, I don't know if you noticed, I have replaced your [] behind .remove with ().)
You are mixing two ways of iterating a list: By index, and by element. In your loop, i is not the index, but the element of the list itself, thus alist[i] won't work.
If you use the for x in somelist loop, then x is the element itself, not the index of the element. For iterating over the indices, you can use for i in range(len(somelist)), or you could use for i, x in enumerate(somelist) to loop over tuples of index and element.
Also note that removing elements from a list or other kinds of collections while you are looping them generally is a bad idea. Better create a copy of the list.
for x in list(alist): # creates a copy of alist
if x < average: # remember: x is the element itselt
alist.remove(x) # remove element x from list
But the way you do it (with eval of a comma-separated string of numbers), alist is a tuple, not a list, and thus has no remove method at all. Thus you either have to convert it to a list before (alist = list(eval(a)), or use one of the approaches given in the other answers, creating a new list using list comprehension or filter and retaining the "good" elements.
As a general principle for asking StackOverflow questions like this, you should always include example input and output -- show what happens, and what you expect to happen.
In this case, I believe there are two three problems with your code:
Edit: Third, but possibly most importantly, look at glglgl's answer. If you implement the two fixes I describe below, you'll still have one problem: your code won't necessarily remove all the items you want to remove, because it'll skip over some items.
First, you say alist[i], which grabs the element of alist at index i. But saying for i in alist makes i be successive elements in the list already. Example:
mylist = [1, 2, 4]
for i in mylist:
print(i)
Would give you the output:
1
2
4
If you instead said this (which is like what you wrote)
mylist = [1, 2, 4]
for i in mylist:
print(mylist[i])
It wouldn't work as you'd expect, because you'd get the element at index 1, the element at index 2, and then try to get the element at index 4, but that wouldn't exist. You'll get something like this:
2
4
IndexError: list index out of range
Second, your syntax for removing an element is wrong. You should use alist.remove(i) instead of alist.remove[i]. You want to call a function, so you use parentheses. The square brackets are for indexing and slicing.

Categories

Resources