Добавление кортежей в списки, присвоение индекса

#python #list #append #tuples

#python #Список #добавить #кортежи

Вопрос:

Я работаю над химической программой, для которой требуется список всех элементов и соответствующих им единиц атомной массы, что-то вроде:

 Elements = [(H,1),(He,2)...(C,12)]
  

все элементы и их AMU считываются из файла, где каждая строка записывается как «C 12». Мне нужно прочитать информацию из файла, добавить каждую строку в отдельный кортеж, а затем добавить кортеж в список. Вот некоторый код, который я безуспешно пробовал.

 class chemistry:
    def readAMU():
        infil = open("AtomAMU.txt", "r")
        line = infil.readline()
        Atoms = list()
        Element = ()
        while line !="":
            line = line.rstrip("n")
            parts = line.split(" ");
            element = parts[0]
            AMU = parts[1]
            element.append(Element)
            AMU.append(Element)
            Element.append(Atoms)
  

Я на правильном пути? Если нет, как бы мне добавить два значения в кортеж, присвоить каждому значение и индекс, а затем добавить это в список?

Комментарии:

1. Вы можете отформатировать свой код, выбрав его и щелкнув значок ‘{ }’.

2. Кортежи неизменяемы. Вы не можете append() ничего с ними сделать, вы должны полностью указать их содержимое при их создании.

3. @rmmh только что исправил это; C достаточно плох для чтения как обычный текст, но Python без отступов — это мазохизм.

4. Вы действительно только что сделали код намного более сложным, чем это было необходимо. Вам не нужен класс или определение — если только вы не планируете извлекать больше данных или повторно использовать определение. Вам также не нужно было создавать так много массивов меньшего размера. Я бы предложил взглянуть на приведенные решения и действительно попытаться понять, что было сделано.

Ответ №1:

Более простым решением является перебор файла с использованием цикла for:

 elements = []
with open("AtomAMU.txt") as f:
    for line in f:
        name, mass = line.split()
        elements.append((name, int(mass)))
  

Комментарии:

1. У меня такие смешанные чувства, когда я вижу подобный вопрос … 10-15 минут чтения некоторой документации по Python.org или Google ответил бы на вопрос. Я понимаю, что это справочный сайт, но немного предварительных усилий избавило бы от необходимости задавать вопросы в первую очередь. Я чувствую запах домашнего задания …

2. @Will: Этот человек приложил усилия для написания кода, который почти работает. Я рад ответить на них.

3. @StevenRumbalski Достаточно верно; я видел хуже, чем это раньше. Я предполагаю, что бывают моменты, когда у меня просто возникает ощущение, что перед публикацией было приложено мало усилий, если таковые вообще были. Возможно, я чувствую, что прилагаю больше усилий, чем другие (я стараюсь не спрашивать, если я действительно не застрял), и поэтому я сужу немного более жестко, чем следовало бы. Как я уже сказал, такие сообщения вызывают у меня смешанные чувства, вот и все.

Ответ №2:

Предполагая, что строки содержат только C 12 и тому подобное и разделены пробелами:

 result = []
for line in open('filename.txt'):
    result.append(line.split())
  

Или, если вам нравится понимание списков:

 [l.split() for l in open('filename.txt')]
  

Обратите внимание, что я предполагаю, что вам было все равно, был ли это кортеж или список. Если это так, просто приведите его:

 [tuple(l.split()) for l in open('filename.txt')]
  

Редактировать: спасибо, Стивен.

Комментарии:

1. Этот код неверен. Он по-прежнему будет содержать новые строки, а элементы в списке будут списками, а не кортежами.

2. @StevenRumbalski: почему это неверно? Я обновил ответ, чтобы удалить readlines вызов, но приведение и разделение кортежей работают так, как они должны, на мой взгляд?

Ответ №3:

Словарь был бы лучшей структурой данных.

 with open("AtomAMU.txt") as f:
    elements_amu = dict(line.split() for line in f)
  

Используйте это следующим образом:

 elements_amu['H']   # gets AMU for H
elements_amu.keys() # list of elements without AMU
  

Ответ №4:

Ваш класс демонстрирует, что вы новичок в Python, поэтому я попытаюсь его очистить и указать на некоторые вещи, не переписывая полностью. Другие решения здесь более чистые, но, надеюсь, это поможет вам понять некоторые концепции.

 class chemistry:
    # Because this is a class method, it will automatically
    # receive a reference to the instance when you call the
    # method. You have to account for that when declaring
    # the method, and the standard name for it is `self`
    def readAMU(self):
        infil = open("AtomAMU.txt", "r")
        line = infil.readline()
        Atoms = list()
        # As Frédéric said, tuples are immutable (which means
        # they can't be changed). This means that an empty tuple
        # can never be added to later in the program. Therefore,
        # you can leave the next line out.
        # Element = ()
        while line !="":
            line = line.rstrip("n")
            parts = line.split(" ");
            element = parts[0]
            AMU = parts[1]
            # The next several lines indicate that you've got the
            # right idea, but you've got the method calls reversed.
            # If this were to work, you would want to reverse which
            # object's `append()` method was getting called.
            # 
            # Original:
            # element.append(Element)
            # AMU.append(Element)
            # Element.append(Atoms)
            # 
            # Correct:
            Element = (element, AMU)
            Atoms.append(Element)
        # If you don't make sure that `Atoms` is a part of `self`,
        # all of the work will disappear at the end of the method
        # and you won't be able to do anything with it later!
        self.Atoms = Atoms
  

Теперь, когда вы хотите загрузить атомарные номера, вы можете создать экземпляр chemistry класса и вызвать его readAMU() метод!

 >>> c = chemistry()
>>> c.readAMU()
>>> print c.Atoms
  

Помните, Atoms является частью c экземпляра из-за последней строки: self.Atoms = Atoms .

Ответ №5:

наслаждайтесь.

 elementlist= []
datafile= open("AtomAMU.txt")
for elementdata in datafile:
    elementlist.append(elementdata.split(" "))
  

Комментарии:

1. не работает … файлу readfile присваивается значение первой строки текста в «AtomAMU.txt «, и файл закрывается. Отбросьте вызов readline() в этой строке, и это сработает.

2. упс. Iv изменил это. Спасибо, кстати.

3. нет проблем; что-то, что легко упустить из виду при быстром объединении кода.