How to check if numbers are in a list in python

Viewed 138

is it possible to check if certain numbers are in a list in python? If so, how do you do it?

My code is as follows:

listA = [["scandium", 1541, 2830], ["titanium", 1668, 3287], ["vanadium", 1910, 3407], ["chromium", 1907, 2671], ["manganese", 1246, 2061], ["iron", 1538, 2862], ["cobalt", 1495, 2870], ["nickel", 1455, 2913], ["copper", 1085, 2562], ["zinc", 419.53, 907]]
listB = [["thing", 999, 333], ["you", 444, 555]] #this is just to test the code

melt = int(input("What is the melting point of your chosen element (in degrees Celcius): "))
boil = int(input("What is the boiling point of your chosen element (in degrees Celcius): "))

if melt in listA:
  for w in listA:
    if melt == w[1]:
      if boil == w[2]:
        print("Is", w[0], "your chosen element?")
if melt not in listA: 
  for x in listB:
    print(x[0]) #also just for testing purposes

I put in the inputs melt == 1541 and boil == 2830 and expected an output of Is scandium your chosen element? but instead got

thing
you

On the contrary, inputs for melt 999 and boil 333 work(ish) with the testing purpose

But how do I check which list the given inputs are in and find out that element?

Thanks in advance

Edit!

Thank you everyone for helping all the answers helped me and I put all the suggestions (except for try except else unless anyone wants to help :D) into my assignment code (this one!). All are correct answers but since I can only mark one, I marked the topmost one. Thank you again!

4 Answers

The first condition is comparing a single value to lists. Drop it, and use instead:

for w in listA:
    if melt == w[1] and boil == w[2]:
        print("Is", w[0], "your chosen element?")
        break

And instead of the second condition (also with wrong comparison) you can add an else clause to the loop with (don't ident the else word, as it belongs to the first for and not to the if):

else:
    for x in listB:
        print(x[0])

If when you input melt the user gives a number, e.g. 1541, then the variable melt will contain an integer, 1541. However, your listA of elements contains list of 3 items, a string, and 2 integers.

Thus, when you test if melt is in the listA, it doesn't find anything because comparing 1541 to ["scandium", 1541, 2830] will return False as both are not equal.

Moreover, using list to store the elements and their boiling point is not ideal. It is difficult to access for instance the elements boiling point as it is nested in the list. A dictionary implementation, or far better, a dataframe implementation (c.f. pandas) will be much more efficient.

To come back to your code, here is a quick fix:

for w in listA:
    if melt == w[1] and boil == w[2]:
        print("Is", w[0], "your chosen element?")

Finally, you also have to deal with input error checking to confirm that the user is inputting valid data.

Edit: dictionaries

With dictionary, you can link a key to a value. The key and the value can be anything: number, list, objects, dictionaries. The only condition is that the key must have the hash() method defined.

For instance, you could store the elements with the string as key, and the 2 temperatures as values.

elements = {"scandium": (1541, 2830), "titanium": (1668, 3287)}

To access an elements, you call elements["scandium"] which will return (1541, 2830). You can also access the elements of a dictionary with 3 functions:

  • elements.keys(): return the keys
  • elements.values(): return the values
  • elements.items(): return the tuples (key, value)

However, once again it is not easy to access the temperatures individually. But this time you can compare it this way:

for key, value in elements.items():
    if (melt, boil) == value:
        print (key)

But even better, since you are looking for the element from the melting and boiling temperature, you can create the following dictionary where the keys are the tuple (boiling, melting) and the value is the corresponding element.

elements = {(1541, 2830): "scandium", (1668, 3287): "titanium"}

Then, once the user inputs melt and boil, you can find the corresponding element with: elements[(melt, boil)]. This time, there is no need to use a loop. The corresponding element can be directly acessed. A similar implementation can be done with a pandas dataframe.

Finally, you could also implement this using a class.

class Element:

    def __init__(self, name, melt, boil):
        self.name = name
        self.melt = melt
        self.boil = boil

elements = [Element("scandium", 1541, 2830), Element("titanium", 1668, 3287)]

As it is, the Element class can not be used as the key of a dictionary. To have it usable as a key, the hash method must be define.

class Element:

    def __init__(self, name, melt, boil):
        self.name = name
        self.melt = melt
        self.boil = boil

    def __key(self):
        return (self.name, self.melt, self.boil)

    def __hash__(self):
        return hash(self.__key())

But again, it is not that simple to access the element from the melt and boil variables. A loop is again necessary.

See below (Note that the code is using namedtuple in order to improve readability)

from collections import namedtuple

ElementProperties = namedtuple('ElementProperties', 'name melting_point boiling_point')
elements = [ElementProperties("scandium", 1541, 2830),
            ElementProperties("titanium", 1668, 3287),
            ElementProperties("vanadium", 1910, 3407),
            ElementProperties("chromium", 1907, 2671),
            ElementProperties("manganese", 1246, 2061),
            ElementProperties("iron", 1538, 2862)]

melt = int(input("What is the melting point of your chosen element (in degrees Celcius): "))
boil = int(input("What is the boiling point of your chosen element (in degrees Celcius): "))

for element in elements:
    if element.melting_point == melt and element.boiling_point == boil:
        print('Your element is: {}'.format(element.name))
        break
else:
    print('Could not find element having melting point {} and boilong point {}'.format(melt, boil))

if the elements are in few lists the code below should work:

from collections import namedtuple

ElementProperties = namedtuple('ElementProperties', 'name melting_point boiling_point')
elements1 = [ElementProperties("scandium", 1541, 2830),
            ElementProperties("titanium", 1668, 3287),
            ElementProperties("vanadium", 1910, 3407),
            ElementProperties("chromium", 1907, 2671),
            ElementProperties("manganese", 1246, 2061),
            ElementProperties("iron", 1538, 2862)]

elements2 = [ElementProperties("hydrogen", 5, 9)]


melt = int(input("What is the melting point of your chosen element (in degrees Celcius): "))
boil = int(input("What is the boiling point of your chosen element (in degrees Celcius): "))

found = False
for element_lst in [elements1,elements2]:
    if found:
        break
    for element in element_lst:
        if element.melting_point == melt and element.boiling_point == boil:
            print('Your element is: {}'.format(element.name))
            found = True
            break
if not found:
    print('Could not find element having melting point {} and boilong point {}'.format(melt, boil))

To make sure that your inputs are indeed numbers, you can do that:

# Check input validity.
while True:
    try:
        melt = int(input("What is the melting point of your chosen element (in degrees Celcius): "))
        boil = int(input("What is the boiling point of your chosen element (in degrees Celcius): "))
        break
    except ValueError:
        continue

# Rest of the work.
...

Basically, inside a loop you ask the user for an input. If int() succeeds, the loop is exited thanks for the break keyword and you can safely assume that melt and boil are integers in the rest of your program. If int() fails, it raises a ValueError and there the continue keyword just ensures that we loop once more.

Related