How to randomly select items in a set - python

For my homework assignment I am supposed to randomly select items in a list. so far I have this code,
import random
room = range(0, 365)
r = random.choice(room)
mySet = set(r)
However, when I attempt to run the program, it says that " 'int' is no iterable".
I was wondering how I can fix this problem?

set() requires an iterable (a list or tuple are iterables) as its argument, where you’ve supplied an integer.

If you want to choose random items (with fixed size) from a set:
list = random.sample(your_set, size);
or if you want to choose random items with random size:
size = random.randint(0, your_set_size):
list = random.sample(your_set, size):

Your set also just has a single value in it so you only have one thing to iterate over. random.choice returns only a single element in the sequence in this case an int. This isn't the cause of the python error (int is not iterable as sneeu says) but will lead to a different result than what you are looking for. random.sample is probably a better choice

However, when I attempt to run the program, it says that " 'int' is no iterable".
I was wondering how I can fix this problem?
Use randint:
>>> from random import randint
>>> randint(0, 360)
86
>>> var = randint(0, 360)
>>> isinstance(var, int)
True
set is actually a type in python, an object like list or dict. Thus, when you pass in an int from random.choice, it gives you an error, because it needs a list, something that you can loop through is an iterable object. So, for example:
>>> set([1,3,4,5,2])
set([1, 2, 3, 4, 5])
Will work, but what you tried to do is this:
>>> set(1) # 1 is used as a number here
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'int' object is not iterable
If you wish to create a random list, you can do something like this:
>>> [randint(0, 360) for _ in xrange(10)]
[234, 122, 294, 71, 204, 360, 359, 318, 273, 212]
The above code creates 10 random integers for you to work with. If you want a set, you can just use the set function to get one, but I think its important for you to understand what set is and what it does. Documentation.

Based on the description of assigment, you needn't initialize set with something. You should only add elements in set in each test and check size of set and number of insertions.
That why init should be like this:
import random
room = range(0, 365)
mySet = set()
P.S. Your code below initialization isn't correct

You have an error because you are creating a set object from an int.
A set should be created from an iterable (like a list) not a single object:
So instead of this :
mySet = set(r)
You should do this :
mySet = set([r])
Why don't you follow the Notes from your homework ?
Notes
For each test, you should use Random.randint to pick a number
between 0 and 365 to use that represents a birthday
randint() returns a random integer without having to create a list, which is what is required with the function you are using :choice()

Related

'float' object is not iterable in for loop

I did research solution of this problem for hours but ı can't find any solution. What is the problem in my code?
import numpy as np
q_max = 5
for q in range(1, q_max):
for p in range(0, q_max):
if q>p:
#I want to delete duplicates numbers
a = list(set(p/q))
print(a)
Error:
Traceback (most recent call last):
File "C:\Users\MONSTER\Desktop\gcd.py", line 16, in <module>
alfa = list(set(p/q))
TypeError: 'float' object is not iterable
If you want unique divisors you have to create your set before you start looping, and then add your values to the set. When you're finished looping, you can print the whole set.
The set will deduplicate values, ignoring .add() calls when items already exist in the set (as opposed to the list's .append() method).
q_max = 5
values = set()
for q in range(1, q_max):
for p in range(0, q_max):
if q>p:
values.add(p/q)
print(values)
Your problem is here:
a = list(set(p/q))
set() will cast an iterable (and only an iterable) into a set object - effectively eliminating duplicates. However, you pass it the result of p / q, which is an int divided by an int - a float. The error states you can't pass a float to a function that expects an iterable.
It's unclear why you want to use set() or even list() here. If your expectation is to divide p by q, just do that. a will be a float you can print.

'int' object has no attribute 'extend' - Python

I am trying to evaluate power series using python. series => e^x = 1+ x+ x^2/2! + x^3/3!...x^n/n!
I am getting this error ''int' object has no attribute 'extend'.
My code:
import math
print('give x')
x = float(input())
n =100
k = 0
list = (1)
while 0<x<1:
list.extend([math.pow(x,K+1))])
k = k+1
if x==n:
break
print(sum(list))
Please help!
There are multiple problems with your code.
Firstly, you are attempting to create a list with (1) - that just creates the integer object 1, the parentheses have no effect here. To create a list containing 1 you need [1]. And you shouldn't use the names of Python built-ins (like list) as variable names - not only is it confusing to other people who may read your code it makes the built-in inaccessible, which can lead to mysterious bugs.
K is not the same as k.
Your while 0<x<1: test does't make much sense; FWIW, the Taylor series for ex converges for all values of x.
Your if x==n: test should be if k==n:, although it'd be better to use a for loop with range (or maybe xrange in Python 2).
You don't need to save the terms in a list - just add them as you go.
You don't need math.pow - x**k calculates the same thing as math.pow(x, k), but even that's unnecessary here: you should just keep track of the previous term and multiply it by x on each loop.
You forgot the /n!. Once again, you don't really need to compute the factorial (or call the math.factorial function) since you can just divide the previous term by k.
Hopefully, that's given you enough clues to fix your code. I won't provide working code at this stage, since I suspect this is a homework problem. Note that the math module has an exp function which you can use to test the accuracy of your power series calculations.
A list literal is created with square brackets, []. You can use parentheses, (), for grouping or for creating a tuple. In the case of list = (1), they are being used for grouping, so this is the same as list = 1. (A tuple with one element is created with mytuple = (1,) or just mytuple = 1,.)
At this point, I'll mention that naming one of your variables list masks the built-in function list, so after you do that you can't access that function anymore without some effort. It's best to name your object something else, like lst.
A list's extend() method adds all the elements from the passed list onto the object you're accessing, so if mylist was [1, 2, 3], mylist.extend([4, 5]) would result in mylist becoming [1, 2, 3, 4, 5]. However, you only have one object to add, so it makes more sense to use append(), which adds the passed object to the given list.
x = float(input('Give x: ')) # the input function can be passed a prompt string
n = 100
k = 0
lst = [1] # changed name, created a list
while 0<x<1:
list.append(x**(k+1)) # you can just use the ** operator if you want
# also, k isn't K
k = k+1
if x==n: # x is never changed, so your loop either never runs
# or goes forever
break
print(sum(lst))
Note the while loop that will either never be entered or never finish. You'll have to take another look at your program's logic.

Lists in Python (how to add the elements)

I just started with Python. Had Haskell before. In Haskell, I worked most of the time with/on lists. In Python I want do so.
I have a list of:
l = [1,2,3,4]
How can I add the 4 elements in the list, so that I get 10 as result (1+2+3+4)
I need a recursive function and an iterative (not clean and stable as iterative , but nevertheless).
In Haskell I did this:
sum [] = 0
sumlist(x:xs) = x + sumlist xs
In Python I tried this:
def sumlist(l)
if l == 0: #or Nil, i do not know
result 0
else:
l [0] + sumlist(l)
but that does not work, maybe I am still to focused on Haskell's implementation style.
Would be great if I get some help.
Edit:
If you do not wish to use sum, you can make your own function1:
>>> def sumlist(seq, start=0):
... return sumlist(seq[1:], start + seq[0]) if seq else start
...
>>> lst = [1, 2, 3, 4]
>>> sumlist(lst)
10
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> sumlist(lst)
45
>>> sumlist(lst, 10) # You can specify a number to start at too
55
>>>
1Note: It is assumed that you will pass in a sequence of numbers.
Just use the sum built-in:
>>> l = [1, 2, 3, 4]
>>> sum(l)
10
>>>
From the docs:
sum(iterable[, start])
Sums start and the items of an iterable from left to right and returns the total. start defaults to 0. The iterable's items are
normally numbers, and the start value is not allowed to be a string.
I haven't used Haskell, but in Python objects are rich in that they know how to work with other objects. You can think of it like the "interface between objects" is well understood, and everyone is expected to behave nicely:
EAFP
Easier to ask for forgiveness than permission. This common Python
coding style assumes the existence of valid keys or attributes and
catches exceptions if the assumption proves false. This clean and fast
style is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common to many
other languages such as C.
So the idea is if there a function in the standard library called sum, you can be sure it does at least two things:
Knows how to sum up things it can sum up.
If it doesn't know how to sum it up, it will raise an Exception.
Once you understand how this works, you can start passing anything to sum to see what it does:
>>> sum((1,2,3)) # a list
6
>>> sum([1,2,3]) # a tuple
6
>>> sum((1,)) # a tuple with one object
1
>>> sum([2]) # a list with one object
2
So as long as the item is iterable, sum can do its thing. Of course, when you pass it something it cannot work with, you get the appropriate exception:
>>> sum(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> sum('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Note that a string is iterable in Python, which is why you get a different exception.
After you comment here:
Is there another way summing them up , or is it just this one ?
Its worth pointing out the zen of python which is kind of a guide on what makes code "pythonic", which states:
There should be one-- and preferably only one --obvious way to do it.
So the obvious way to sum things up would be with a function named sum.
Your code isn't actually too far off. empty lists are "falsy", so you can do something like:
def sumlist(lst):
if not lst:
return 0
else:
# Add the first element to the sum of the remaining elements.
return lst[0] + sumlist(lst[1:])
Of course, I'm assuming that you're doing this as part of a homework assignment where you're learning about recursion -- This would be horrible in any sort of production code where you should really just use sum (the builtin function).
If you are looking for a method other than the obvious sum you can use reduce:
>>> l = [1,2,3,4]
>>> import operator
>>> reduce(operator.add, l)
10
If you want another function, you could do:
def sum_l(l):
rtr=0
while l:
rtr+=l.pop()
return rtr
That function is destructive to the list. If you want to keep the list, call it with a copy of the list:
n=sum_l(l[:])
Yet another (that does not destroy the list) is to use a for loop on the iterable:
def sum_l(l):
rtr=0
for e in l:
rtr+=e
return rtr
Here are two ways you can compute the sum:
Just use the in-built sum function:
sum(l)
Using a for loop:
sum_val = 0
for i in range(0, len(l)):
sum_val += l[i]
Using recursion to compute a sum is just waste of computing resources. Do not use recursion until its absolutely necessary.

Invalid syntax when creating lists

So i am attempting to create 3 different lists one of 1k, one of 10k, and one of 100k items long populated with random numbers from 1 to 10million but i cant seem to figure out why it keeps saying its invalid syntax. So far i have:
edit: okay it seems to have fixed the invalid syntax problem with some tweaking but still gives me:
Traceback (most recent call last):
File "C:/Python32/funtime.py", line 16, in <module>
print (list[1])
TypeError: 'type' object is not subscriptable
this is exactly what i have typed in:
import random
def createlist(a):
blist =[]
count=0
while count <= a:
blist.append(random.randint(1,10000000))
count= count+1
return blist;
list1= createlist(10000);
print (list[1])
Traceback (most recent call last):
File "C:/Python32/funtime.py", line 16, in <module>
print (list[1])
TypeError: 'type' object is not subscriptable
Objects of type type are indeed not subscriptable. list is the name of the builtin list class, which is an instance of type. It doesn't make any sense to subscript it, so that's clearly not what you intended to do.
You meant print (list1[1]). list1 is the name you bound to your list object created by createlist(10000).
The trick to finding these sort of bugs is to look at the error message Python gave you. It's telling you exactly the problem line, and exactly why it's a problem. All that was missing was the realisation that list is not the name of the object you wanted to subscript.
A much shorter version would be:
>>> import random
>>> def create_list(length):
... return [random.randint(1,1000000) for _ in range(length)]
This demonstrates a couple of things:
A much more compact way to loop x times (the for _ in range(length) idiom)
List comprehensions to create lists, instead of repeated calls to append.
The use of _ as a variable name when you need the variable, but not the actual data in it. This is a somewhat common convention that crops up most often in list comprehensions. It isn't a problem not to use it, but it crops up often enough that it pays to be aware of it.
Hat-tip to #mgilson for his comment on another answer that reminded me the _ convention.
The following works fine on my system.
import random
def createlist(a):
blist =[]
count= 0
while count <= a:
blist.append(random.randint(1,1000000))
count=count+1
return blist
list1= createlist(10000)
print list1[1]
http://ideone.com/SL2bL <-- try it here.
I'd probably do it like this
import random
def createlist(a):
return [random.randint(1,1000000) for i in xrange(a)]
list1= createlist(10000)
print list1[1]
Or probably just skip the function..
list1 = [random.randint(1,1000000) for i in xrange(a)]
print list1[1]
As some other answers have stated, you could easily use list comprehension for something like this (the so-called Pythonic way):
somelist = [random.randint(1, 1000000) for i in xrange(10000)]
List comprehension is fast in Python because it is executed by underlying C code. Moreover, using xrange is more memory-efficient.
Note: By convention, when the loop-control variable is not used in Python, it is named _:
somelist = [random.randint(1, 1000000) for _ in xrange(10000)]
use a list comprehension (its way betta and makes you look pro, haha)
[random.randint(1, 1000000) for i in range(10000)]
First, you don't put a paren by while unless you're evaluating complex expressions.
Next, you used a semicolon to return your blist. Not necessary.
Finally...why not use a for loop?
import random
def createlist(a):
blist =[]
for x in xrange(a):
blist.append(random.randint(1,1000000))
return blist
list1= createlist(10000)
print list1[0]

How do I get the number of elements in a list (length of a list) in Python?

How do I get the number of elements in the list items?
items = ["apple", "orange", "banana"]
# There are 3 items.
The len() function can be used with several different types in Python - both built-in types and library types. For example:
>>> len([1, 2, 3])
3
How do I get the length of a list?
To find the number of elements in a list, use the builtin function len:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
And now:
len(items)
returns 3.
Explanation
Everything in Python is an object, including lists. All objects have a header of some sort in the C implementation.
Lists and other similar builtin objects with a "size" in Python, in particular, have an attribute called ob_size, where the number of elements in the object is cached. So checking the number of objects in a list is very fast.
But if you're checking if list size is zero or not, don't use len - instead, put the list in a boolean context - it is treated as False if empty, and True if non-empty.
From the docs
len(s)
Return the length (the number of items) of an object. The argument may be a sequence (such as a string, bytes, tuple, list, or range) or
a collection (such as a dictionary, set, or frozen set).
len is implemented with __len__, from the data model docs:
object.__len__(self)
Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t
define a __nonzero__() [in Python 2 or __bool__() in Python 3] method and whose __len__() method returns zero
is considered to be false in a Boolean context.
And we can also see that __len__ is a method of lists:
items.__len__()
returns 3.
Builtin types you can get the len (length) of
And in fact we see we can get this information for all of the described types:
>>> all(hasattr(cls, '__len__') for cls in (str, bytes, tuple, list,
range, dict, set, frozenset))
True
Do not use len to test for an empty or nonempty list
To test for a specific length, of course, simply test for equality:
if len(items) == required_length:
...
But there's a special case for testing for a zero length list or the inverse. In that case, do not test for equality.
Also, do not do:
if len(items):
...
Instead, simply do:
if items: # Then we have some items, not empty!
...
or
if not items: # Then we have an empty list!
...
I explain why here but in short, if items or if not items is both more readable and more performant.
While this may not be useful due to the fact that it'd make a lot more sense as being "out of the box" functionality, a fairly simple hack would be to build a class with a length property:
class slist(list):
#property
def length(self):
return len(self)
You can use it like so:
>>> l = slist(range(10))
>>> l.length
10
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Essentially, it's exactly identical to a list object, with the added benefit of having an OOP-friendly length property.
As always, your mileage may vary.
Besides len you can also use operator.length_hint (requires Python 3.4+). For a normal list both are equivalent, but length_hint makes it possible to get the length of a list-iterator, which could be useful in certain circumstances:
>>> from operator import length_hint
>>> l = ["apple", "orange", "banana"]
>>> len(l)
3
>>> length_hint(l)
3
>>> list_iterator = iter(l)
>>> len(list_iterator)
TypeError: object of type 'list_iterator' has no len()
>>> length_hint(list_iterator)
3
But length_hint is by definition only a "hint", so most of the time len is better.
I've seen several answers suggesting accessing __len__. This is all right when dealing with built-in classes like list, but it could lead to problems with custom classes, because len (and length_hint) implement some safety checks. For example, both do not allow negative lengths or lengths that exceed a certain value (the sys.maxsize value). So it's always safer to use the len function instead of the __len__ method!
And for completeness (primarily educational), it is possible without using the len() function. I would not condone this as a good option DO NOT PROGRAM LIKE THIS IN PYTHON, but it serves a purpose for learning algorithms.
def count(list): # list is an iterable object but no type checking here!
item_count = 0
for item in list:
item_count += 1
return item_count
count([1,2,3,4,5])
(The list object must be iterable, implied by the for..in stanza.)
The lesson here for new programmers is: You can’t get the number of items in a list without counting them at some point. The question becomes: when is a good time to count them? For example, high-performance code like the connect system call for sockets (written in C) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);, does not calculate the length of elements (giving that responsibility to the calling code). Notice that the length of the address is passed along to save the step of counting the length first? Another option: computationally, it might make sense to keep track of the number of items as you add them within the object that you pass. Mind that this takes up more space in memory. See Naftuli Kay‘s answer.
Example of keeping track of the length to improve performance while taking up more space in memory. Note that I never use the len() function because the length is tracked:
class MyList(object):
def __init__(self):
self._data = []
self.length = 0 # length tracker that takes up memory but makes length op O(1) time
# the implicit iterator in a list class
def __iter__(self):
for elem in self._data:
yield elem
def add(self, elem):
self._data.append(elem)
self.length += 1
def remove(self, elem):
self._data.remove(elem)
self.length -= 1
mylist = MyList()
mylist.add(1)
mylist.add(2)
mylist.add(3)
print(mylist.length) # 3
mylist.remove(3)
print(mylist.length) # 2
Answering your question as the examples also given previously:
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print items.__len__()
You can use the len() function to find the length of an iterable in python.
my_list = [1, 2, 3, 4, 5]
print(len(my_list)) # OUTPUT: 5
The len() function also works with strings:
my_string = "hello"
print(len(my_string)) # OUTPUT: 5
So to conclude, len() works with any sequence or collection (or any sized object that defines __len__).
There is an inbuilt function called len() in python which will help in these conditions.
>>> a = [1,2,3,4,5,6]
>>> len(a) # Here the len() function counts the number of items in the list.
6
This will work slightly different in the case of string: it counts the characters.
>>> a = "Hello"
>>> len(a)
5
There are three ways that you can find the length of the elements in the list. I will compare the 3 methods with performance analysis here.
Method 1: Using len()
items = []
items.append("apple")
items.append("orange")
items.append("banana")
print(len(items))
output:
3
Method 2: Using Naive Counter Method
items = []
items.append("apple")
items.append("orange")
items.append("banana")
counter = 0
for i in items:
counter = counter + 1
print(counter)
output:
3
Method 3: Using length_hint()
items = []
items.append("apple")
items.append("orange")
items.append("banana")
from operator import length_hint
list_len_hint = length_hint(items)
print(list_len_hint)
output:
3
Performance Analysis – Naive vs len() vs length_hint()
Note: In order to compare, I am changing the input list into a large set that can give a good amount of time difference to compare the methods.
items = list(range(100000000))
# Performance Analysis
from operator import length_hint
import time
# Finding length of list
# using loop
# Initializing counter
start_time_naive = time.time()
counter = 0
for i in items:
# incrementing counter
counter = counter + 1
end_time_naive = str(time.time() - start_time_naive)
# Finding length of list
# using len()
start_time_len = time.time()
list_len = len(items)
end_time_len = str(time.time() - start_time_len)
# Finding length of list
# using length_hint()
start_time_hint = time.time()
list_len_hint = length_hint(items)
end_time_hint = str(time.time() - start_time_hint)
# Printing Times of each
print("Time taken using naive method is : " + end_time_naive)
print("Time taken using len() is : " + end_time_len)
print("Time taken using length_hint() is : " + end_time_hint)
Output:
Time taken using naive method is : 7.536813735961914
Time taken using len() is : 0.0
Time taken using length_hint() is : 0.0
Conclusion
It can be clearly seen that time taken for naive is very large compared to the other two methods, hence len() & length_hint() is the best choice to use.
To get the number of elements in any sequential objects, your goto method in Python is len() eg.
a = range(1000) # range
b = 'abcdefghijklmnopqrstuvwxyz' # string
c = [10, 20, 30] # List
d = (30, 40, 50, 60, 70) # tuple
e = {11, 21, 31, 41} # set
len() method can work on all the above data types because they are iterable i.e You can iterate over them.
all_var = [a, b, c, d, e] # All variables are stored to a list
for var in all_var:
print(len(var))
A rough estimate of the len() method
def len(iterable, /):
total = 0
for i in iterable:
total += 1
return total
Simple: use len(list) or list.__len__()
In terms of how len() actually works, this is its C implementation:
static PyObject *
builtin_len(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
{
Py_ssize_t res;
res = PyObject_Size(obj);
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
return PyLong_FromSsize_t(res);
}
Py_ssize_t is the maximum length that the object can have. PyObject_Size() is a function that returns the size of an object. If it cannot determine the size of an object, it returns -1. In that case, this code block will be executed:
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
And an exception is raised as a result. Otherwise, this code block will be executed:
return PyLong_FromSsize_t(res);
res which is a C integer, is converted into a Python int (which is still called a "Long" in the C code because Python 2 had two types for storing integers) and returned.

Categories

Resources