looking at a number in a tuple - python

Right now my function is not recoginizing my numbers in the list coeff as numbers. I am trying to pair up items from the two list and then sort them into a different list based on the value of mul. But everything is going into the negative list. How to i make sure it is considering mul as a number going into each if statement.
def balance_equation(species,coeff):
data=zip(coeff,species)
positive=[]
negative=[]
for (mul,el) in data:
if mul<0:
negative.append((el,mul))
if mul>0:
positive.append((el,mul))
Edit;
I ment to originally include this
balance_equation(['H2O','A2'],['6','-4'])

Your problem is that in the way you call it (balance_equation(['H2O','A2'],['6','-4'])), mul is a string rather than an int ('6' or '-4' rather than 6 or -4). Change your if statement to:
if int(mul)<0:
negative.append((el,mul))
if int(mul)>0:
positive.append((el,mul))
This converts mul to an integer before comparing it to 0.

Well, the first problem is that your function just returns None, just throwing away the two lists, so there's no way to even see whether it's doing the right thing.
If you fix that, you'll see that it is doing the right thing.
def balance_equation(species,coeff):
data=zip(coeff,species)
positive=[]
negative=[]
for (mul,el) in data:
if mul<0:
negative.append((el,mul))
if mul>0:
positive.append((el,mul))
return negative, positive
>>> n, p = balance_equation(balance_equation('abcdef', range(-3,3))
>>> n
[('a', -3), ('b', -2), ('c', -1)]
>>> p
[('e', 1), ('f', 2)]
So, there are two possibilities:
Since the code you pasted is clearly not the actual code you're running, maybe you fixed the bug while rewriting it to post here.
You're not calling it with sensible inputs. For example, if you pass the parameters backward, since species is presumably a collection of strings, they'll all end up positive. Or, likewise, if you pass the coeffs as string representations of integers.
If it's the last problem—you're passing, say, 'abcdef', ['-3', '-2', '-1', '0', '1', '2', '3'], and you want to deal with that within balance_equation instead of in the calling code, that's easy. Just add this line before the zip:
coeff = [int(x) for x in coeff]
Or change your zip to:
data = zip((int(x) for x in coeff), species)
By the way, I'm assuming you're on CPython 2. In Python 3, trying to compare a string to 0 will raise a TypeError instead of always returning True, while in other Python 2 implementations it might always return False instead of True…

I think you have your answer, but there's also a simpler way of doing this in Python:
for (mul, el) in data:
append_to = negative.append if mul < 0 else positive.append
append_to(el)
Not sure what "should happen" to 0 though

Related

Create a list of shared components of another list and a string?

I have two variables:
myList = [(0, 't'), (1, 'r'), (2, '_')]
newList = []
I want to create a new list, which includes tuples that have alphabet character inside. The output should be:
newList = [(0, 't'), (1, 'r')]
My initial thought is:
for thing in myList:
if thing(1) in string.ascii_lowercase: #This line doesn't work.
newList.append(thing)
I have 2 questions:
Please help me with the broken code. Can you tell me the name of the error, for a beginner, it's even hard to know the right word to search google.
Please give advice on naming things. Like in this example, how would you name thing?
You need to change:
if thing(1) in string.ascii_lowercase:
to:
if thing[1] in string.ascii_lowercase:
Also make sure you have importedstring.
You can rename thing to list_tuple or my_list_object for example. You will get good at naming eventually.
The "Pythonic" way to accomplish your goal is as follows:
import string
newList = filter(lambda x: type(x) is tuple and x[1] in string.ascii_lowercase, myList)
Explanation:
import string: importing the string module to obtain a list of all alphabet
filter(condition, iterable): an extremely useful, builtin, function of Python which allows you to filter out unwanted elements from a list (or any other iterable for that matter)
lambda x: an (usually simple) anonymous function defined at runtime which operates on a runtime variable x
type(x) is tuple and x[1] in string.ascii_lowercase: when operating on each element x in the iterable passed to filter, the lambda function first verifies that the element is indeed a tuple, and if so, checks if the first element is in the lowercased alphabet
Hope this helps

choosing a random number from a tuple + some numbers

I have a tuple of numbers, and I want to choose a random number from my tuple in addition with a certain number. For example:
my_tuple = (1,2,3)
and I have the number 4. I want to choose a random number from the numbers 1,2,3,4 (without changing the tuple of course).
I tried:
my_tp = (1, 2, 3)
a = random.choice(list(my_tp).append(4))
print(a)
I'm new to python. I tried converting the tuple to a list, and then performing the random function.
The code above didn't work. Got the error
object of type 'NoneType' has no len()
Would love some help.
list.append returns none
Once converting to a list as you have done, appending will modify that list but return none so that is the source of your error.
To get round that you can either convert the tuple to a list then append 4 to it, then use random.choice, or in just one step, you can concatenate a list of [4] with the + operand.
This approach is much simpler:
import random
my_tuple = (1,2,3)
random.choice(list(my_tuple) + [4])
Hope this helps and clears some things up! :)
Update:
If you want to just randomly select from the tuple without the last item, then just slice the list with the normal syntax:
random.choice(list(my_tuple)[:-1])
The method list.append alters the provided list and returns None, which explains the exception you got. To get the desired result, you can implicitly use the tuple.__add__ method, which will return a new tuple.
values = (1, 2, 3)
random.choice(values + (4,))
If you want to remove values in a concise-ish fashion, using a set might be appropriate.
values = {1, 2, 3}
random.choice(list(values - {3}))
You can try:
my_tuple = (1,2,3)
random.choice((*my_tuple, 4))
Where (*my_tuple, 4) creates a new tuple with the unpacked content of my_tuple and 4.

Python Function returning string with quotes

I have a function and returning three values, The return value for my function is
(1, 3, "<class 'int'>")
while I want to return
(1, 3, <class 'int'>)
How do I remove the quotes from my return value.str(type(element)) is the value which is returning the 3rd value
def is_list_permutation(L1, L2):
L1set = set(L1)
L2set = set(L2)
count = 0
element = ''
if L1 == [] and L2 == []:
return(None,None,None)
elif len(L1) == len(L2) and L1set == L2set:
for a in L1:
if L1.count(a) == L2.count(a):
if L1.count(a) > count:
count = L1.count(a)
element = a
return(element,count,str(type(element)))
else:
return False
break
else:
return False
so if i give
L1 = [1, 'b', 1, 'c', 'c', 1]
L2 = ['c', 1, 'b', 1, 1, 'c']
then the result is (1, 3, "<class 'int'>") while I want (1, 3, <class 'int'>)
Your function is returning a tuple with three elements: element, count and the string representation of the type of element. At no point, this has any string representation which you’re seeing there. You just get back a tuple.
Now, when you print that tuple, then the print function will actually try to convert it into a string. For a tuple, this string representation is defined to be a set of parentheses (), and the repr() string representation of each tuple element inside.
For numbers, this will look fine since repr(5) happens to be the string '5'. But for strings, the repr will add quotes to make sure that the return string would be valid Python code:
>>> repr('foo')
"'foo'"
>>> print(repr('foo'))
'foo'
Now, when you say, you want the result without those quotes, you have to think about what that actually means. You could easily format the result string yourself. For example like this:
return '({0}, {1}, {2})'.format(element, count, str(type(element)))
This will return a string that would look like the way you want.
However, by doing that, you also lose the information you had when you returned a tuple. Now, you just return a string that has no information about the actual source values. So you cannot take the count value out without parsing the string again.
So, think about what you want to do: Do you actually just want something nice to print, or do you actually want to get those three values individually as a return value to be able to use them for something else afterwards?
You could always consider printing the text in the desired format later, if you already have the return values as a tuple…
Btw.: Note that when not calling str(type(element)) but just type(element), you would get back a type element (instead of a string). And the repr() of a type element happens to be exactly what you would want to have. So as a quick fix, you could always get rid of that str() call there.
There will always be some quotes around it because it is a string!
If you want to return None when the string is "" then you could do this:
x = str(type(s))
return(element, count, x if x else None)

Why are tuples enclosed in parentheses?

a tuple is a comma-separated list of values
so the valid syntax to declare a tuple is:
tup = 'a', 'b', 'c', 'd'
But what I often see is a declaration like this:
tup = ('a', 'b', 'c', 'd')
What is the benefit of enclosing tuples in parentheses ?
From the Python docs:
... so that nested tuples are interpreted correctly. Tuples may be
input with or without surrounding parentheses, although often
parentheses are necessary anyway (if the tuple is part of a larger
expression).
Example of nested tuples:
tuple = ('a', ('b', 'c'), 'd')
The parentheses are just parentheses - they work by changing precedence. The only exception is if nothing is enclosed (ie ()) in which case it will generate an empty tuple.
The reason one would use parentheses nevertheless is that it will result in a fairly consistent notation. You can write the empty tuple and any other tuple that way.
Another reason is that one normally want a literal to have higher precedence than other operations. For example adding two tuples would be written (1,2)+(3,4) (if you omit the parentheses here you get 1,2+3,4 which means to add 2 and 3 first then form the tuple - the result is 1,5,4). Similar situations is when you want to pass a tuple to a function f(1,2) means to send the arguments 1 and 2 while f((1,2)) means to send the tuple (1,2). Yet another is if you want to include a tuple inside a tuple ((1,2),(3,4) and (1,2,3,4) are two different things.
Those are good answers! Here's just an additional example of tuples in action (packing/unpacking):
If you do this
x, y = y, x
what's happening is:
tuple_1 = (y, x)
(x, y) = tuple_1
which is the same as:
tuple_1 = (y, x)
x = tuple_1[0]
y = tuple_1[1]
In all these cases the parenthesis don't do anything at all to the python. But they are helpful if you want to say to someone reading the script "hey! I am making a tuple here! If you didn't see the comma I'll add these parenthesis to catch your eye!"
Of course the answers about nested tuples are correct. If you want to put a tuple inside something like a tuple or list...
A = x, (x, y) # same as (x, (x, y))
B = [x, (x, y)]

Trying to find majority element in a list

I'm writing a function to find a majority in a Python list.
Thinking that if I can write a hash function that can map every element to a single slot in the new array or to a unique identifier, perhaps for a dictionary, that should be the best and it should be undoable. I am not sure how to progress. My hash function is obviously useless, any tips on what I can/should do, or if this is even a reasonable approach?
def find_majority(k):
def hash_it(q):
return q
map_of = [0]*len(k)
for i in k:
mapped_to = hash_it(i) #hash function
map_of[mapped_to]+=1
find_majority([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
Python has a built-in class called Counter that will do this for you.
>>> from collections import Counter
>>> c = Counter([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
>>> c.most_common()
[(3, 5), (2, 4), (4, 4), (1, 3), (5, 3), (6, 2)]
>>> value, count = c.most_common()[0]
>>> print value
3
See the docs.
http://docs.python.org/2/library/collections.html#collections.Counter
There is an easy way to realize like this
l = [1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5]
print(max(set(l), key = l.count)) # 3
I think your approach is to use another array as big as k as your "hash map". If k is huge but the number of unique elements is not so huge, you would be wasting a lot of space. Furthermore, to find the majority, you would have to loop through your map_of hashmap/array to find the max.
On the other hand, a dictionary/set (where hashing is not your concern, and the underlying array structure will probably be more compact for average cases) seems a little more appropriate. Needless to say, with the occurring elements as keys and their occurrences as values, you can find what you want in one single iteration.
So, something like:
def find_majority(k):
myMap = {}
maximum = ( '', 0 ) # (occurring element, occurrences)
for n in k:
if n in myMap: myMap[n] += 1
else: myMap[n] = 1
# Keep track of maximum on the go
if myMap[n] > maximum[1]: maximum = (n,myMap[n])
return maximum
And as expected, we get what we want.
>>> find_majority([1,2,3,4,3,3,2,4,5,6,1,2,3,4,5,1,2,3,4,6,5])
(3, 5)
Of course, Counters and other cool modules will let you do what you want in finer syntax.

Categories