Append a counter to a set - python

I have a for loop where I count in i in range(0, 999999999) and I want to add these in a set with a second variable, for example (pseudo code):
import random
the_set = set()
for i in range(0, 999999999):
x = random.randint(0,100)
the_set.append(str(i)+":"+str(x))
i and x are example variables where in this case the elements in the set are always unique, I understand that, but with the actual variables non-uniques may occur but shouldn't be in the set.
How do I define such a set and .append() values?

Python set doesn't have append method, but they have add. So, you can do
the_set.add(str(i)+":"+str(x))
In this case, you can simply use set comprehension, like this
the_set = {"{}:{}".format(i, random.randint(0,100)) for i in range(999999999)}
But the actual problem here is 999999999. It is a very big number. So, its not advisable to build a set of that size and holding it in memory. If you are just going to use this as a unique number generator, you can simply use a generator, like this
def get_next_number(max_number):
for i in xrange(max_number): # use `range` if you are using Python 3.x
yield "{}:{}".format(i, random.randint(0,100))
And then you can use it in a loop like this
for new_number in get_next_number(999999999):
print new_number

If I understand correctly, your goal is to ignore x if it has already been generated, I think you might want to use a dictionary instead:
the_dict()
for i in range(0, 999999999):
x = random.randint(0,100)
if the_dict.has_key(x):
continue
the_dict[x] = i
you could build the resulting set afterward:
the_set = {'%i:%i' % (value, key) for key, value in the_dict.iteritems()}

the_set = {'{}:{}'.format(i, random.randint(0,100)) for i in xrange(10)}

Related

Need to make a list from a function

I want to change the a variable from 1 to 50 and create an array from the results so that I can feed it into a curve.
The variable is outside the function but the variable changes a value in the function, that is what I need to make a list of.
a=1
def test(foo):
p =a+2
print(p)
test(foo)
I want to get the p values when I change a from 1 to 50:
[3,4,5,6,7,8,9...]
Not sure what you trying to do but if you need a list of numbers with some starting point, you can simply generate them using list comprehension as:
a = 2
x = [i+a for i in range(1, 50)]
print(x)
EDIT: Based on comments from author.
You need to change print to return the generated number. Also, need to add a loop and a list to generate a new number and keep appending the new number to the list.
Note: As said earlier, it is recommended to use Python's supported features like list comprehension as is shown in the original code.
a = 1
def test(i):
p = a + i
return p
res = []
for i in range(2, 50):
res.append(test(i))
print(res)

function would not change the parameter as wanted

here is my code
def common_words(count_dict, limit):
'''
>>> k = {'you':2, 'made':1, 'me':1}
>>> common_words(k,2)
>>> k
{'you':2}
'''
new_list = list(revert_dictionary(count_dict).items())[::-1]
count_dict = {}
for number,word in new_list:
if len(count_dict) + len(word) <= limit:
for x in word:
count_dict[x] = number
print (count_dict)
def revert_dictionary(dictionary):
'''
>>> revert_dictionary({'sb':1, 'QAQ':2, 'CCC':2})
{1: ['sb'], 2: ['CCC', 'QAQ']}
'''
reverted = {}
for key,value in dictionary.items():
reverted[value] = reverted.get(value,[]) + [key]
return reverted
count_dict = {'you':2, 'made':1, 'me':1}
common_words(count_dict,2)
print (count_dict)
what i expected is to have the count_dict variable to change to {'you':2}.
It did work fine in the function's print statement, but not outside the function..
The problem, as others have already written, is that your function assigns a new empty dictionary to count_dict:
count_dict = {}
When you do this you modify the local variable count_dict, but the variable with the same name in the main part of your program continues to point to the original dictionary.
You should understand that you are allowed to modify the dictionary you passed in the function argument; just don't replace it with a new dictionary. To get your code to work without modifying anything else, you can instead delete all elements of the existing dictionary:
count_dict.clear()
This modifies the dictionary that was passed to the function, deleting all its elements-- which is what you intended. That said, if you are performing a new calculation it's usually a better idea to create a new dictionary in your function, and return it with return.
As already mentioned, the problem is that with count_dict = {} you are not changing the passed in dictionary, but you create a new one, and all subsequent changes are done on that new dictionary. The classical approach would be to just return the new dict, but it seems like you can't do that.
Alternatively, instead of adding the values to a new dictionary, you could reverse your condition and delete values from the existing dictionary. You can't use len(count_dict) in the condition, though, and have to use another variable to keep track of the elements already "added" to (or rather, not removed from) the dictionary.
def common_words(count_dict, limit):
new_list = list(revert_dictionary(count_dict).items())[::-1]
count = 0
for number,word in new_list:
if count + len(word) > limit:
for x in word:
del count_dict[x]
else:
count += len(word)
Also note that the dict returned from revert_dictionary does not have a particular order, so the line new_list = list(revert_dictionary(count_dict).items())[::-1] is not guaranteed to give you the items in any particular order, as well. You might want to add sorted here and sort by the count, but I'm not sure if you actually want that.
new_list = sorted(revert_dictionary(count_dict).items(), reverse=True)
just write
return count_dict
below
print count_dict
in function common_words()
and change
common_words(count_dict,2)
to
count_dict=common_words(count_dict,2)
So basically you need to return value from function and store that in your variable. When you are calling function and give it a parameter. It sends its copy to that function not variable itself.

Python 2.7: How would I go about creating a dictionary that maps the first n numbers to their respective squares or cubes?

I currently have this piece of code (for squares), but it doesn't seem to be working correctly:
for n in range(len(dict)):
if n == 0:
pass
else:
squares = (n*n)
dict[n]=squares
The parameter of range() should be n, because the dictionary is probably empty when you begin.
Also, dict is a builtin type in python and you shouldn't name your variables this way.
squares = {i:i*i for i in xrange(n)}
dict={}
for i in range(n):
dict[i]=i*i
squares={}
for r in range(int(n) + 1):
if r == 0:
pass;
else:
squares[r] = (r * r)
This code will create a dictionary, look through all of the values up to n, and add the square tot he dictionary at index "r"! This code fulfills all of the requirements you asked for! Let me know if you have any questions!
It's not clear from the question whether dict already contains values. Also I'm not sure why you're skipping n==0.
Assuming you have a list dict with a certain length, your code should work for all values except the first (which you're skipping), except that your last line is not indented, so it's not run inside the loop. This should do it:
for n in range(len(dict)):
dict[n]=n*n
Anyway I recommend a list comprehension to do this:
dict = [n*n for n in len(dict)]

What is a set? And what does "a for a in i" do?

I came across these constructs and I'm not quite sure what they do. Can someone explain?
setx = set([a for a in i])
sety = set([y for y in j])
Code, for context
a = int(input())
for i in range(a):
i = (input())
j = (input())
setx = set([a for a in i])
sety = set([y for y in j])
if setx.intersection(sety) == set():
print("NO")
else:
print("YES")
[a for a in i] is a list comprehension. It's basically a concise way to make a list.
They can be really useful, or they can be source of much unreadable code, or both. The full syntax is
[f(i) for i in iterator if conditional(i)]
examples:
List of squares: [i**2 for i in range(n)]
List of squares not divisible by 5: [i**2 for i in range(n) if i**2 % 5 =! 0]
And as for set: Set is a very useful data type in python. It's basically a dictionary without the values. All elements must be unique and hashable, and sets do not store order, but checking to see if an object is in a set is not dependent on the length of the set.
In this case, your code is probably using sets to make figuring out if the two inputs share any commonalities faster and easier to write.
(Also, finally: Uh, as posted, I don't really know what your code does, but I can be pretty sure it doesn't what it wants to. If I were to rewrite it, it'd be something like
a = int(input())
setx = set() #initializing empty sets
sety = set()
for _ in range(a): #underscore often used when you don't care about what you're iterating over, just that you iterate a certain amount of times.
setx.add(input()) #Previously, you'd just get the last input
sety.add(input()) #I doubt that's what you wanted
if setx.intersection(sety): #no need to compare to empty set. if set() will evaluate as false
print("NO")
else:
print("YES")
)
Set is build-in data type: a collection of unordered unique elements, strong on unique.
For more specifics see the amazing python Docs: For example See [https://docs.python.org/3.5/library/stdtypes.html?highlight=set#set]
So using set() over that list comprehension it is removing duplicates from the list.

How do I handle the following situation in Python?

I want to say
a[current] = value
rather than saying
a.append(value)
because I want to show that the current value is value. The former listing shows this better. I come from C, so I am a bit confused with python lists. In C I preallocate space, so a[current] would exist and contain junk before I assign it value. Can I do something similar in Python?
You can do something like
[0] * 10
which will result in
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But your approach will probably not be very "pythonic". If switching to Python, you should also think about thinking in python. ;-)
When I first started using Python I ran into this problem all the time. You can do things like '[0]*10', but is inelegant, and will cause you problems if you try to do the same thing for lists of lists.
I finally solved the problem by realizing most of the time I just needed to reformulate the problem into something more pythonic. List comprehensions (as noted above) will almost always be the correct answer. If you are preallocating space, that means you are probably going to iterate over some other list, do some operation, then set an element in the new list to that value:
newList = [op(e) for e in oldList]
You can get fancier. If for example, you don't want all the elements, you can set up a filter:
newList = [op(e) for e in oldList if e < 5]
which will only put items that are less than 5 into the newList.
However, sometimes list comprehension isn't want you want. For example, if you're doing math-oriented coding, then numpy can come to the rescue:
myVector = numpy.zeros(10)
will create an array with 10 elements.
You can allocate a list of length n by using
my_list = [None] * n
Obviously, the list will be initialised rather than containing junk.
That said, note that often a list comprehension is a good replacement for a loop containing calls to list.append().
If you want to create a list with n elements initialized to zero (read "preallocate") in Python, use this:
somelist = [0] * n
Is this what you want?
If you don't like append, you can do things like
a = [None]*10
for i in range(10):
a[i] = something()
you might be interested also in python arrays.
I think that the most approximate syntax would be:
a.insert(current, value)
but if current isn't the last position in the array, insert will allocate some extra space and shift everything after current in one position. Don't know if this is the desired behavior. The following code is just like an append:
a.insert(len(a), value)
If you want to show that the current value is 'value', why don't you just use a variable for it?
a.append(value)
current_value = value
If you are maintaining a separate current variable to indicate where the next item will be inserted (that is, your line a[current] = value is followed immediately by current += 1 and you wish you could just write a[current++] = value), then you're writing C in Python and should probably stop. :-)
Otherwise you probably want to preallocate the list with the number of items you want it to contain, as others have shown. If you want a list that will automatically extend to fill in missing values, such that a[100] = value will work even if the list only has 50 items, this can be done with a custom __setitem__() method on a list subclass:
class expandinglist(list):
def __setitem__(self, index, value):
length = len(self)
if index < length:
list.__setitem__(self, index, value)
elif index = length: # you don't actually need this case, it's just a bit
self.append(value) # faster than the below for adding a single item
else:
self.extend(([0] * (index - length)) + [value])
lyst = expandinglist()
lyst[5] = 5
print lyst
>> [0, 0, 0, 0, 0, 5]

Categories

Resources