Как понять этот код, разбить массив в Python? - PullRequest
0 голосов
/ 03 ноября 2011

Я немного запутался по поводу строки в Python:

Мы используем Python и пользовательскую функцию для разделения строки: мы хотим, чтобы то, что находится в кавычках, было единственной записью в массиве.

Строка, например:

"La Jolla Bank, FSB",La Jolla,CA,32423,19-Feb-10,24-Feb-10

Таким образом, «La Jolla Bank, FSB» должен быть одной записью в массиве.

И я не уверен, что понимаю этот код:

  1. Первый символ представляет собой кавычку '"', поэтому переменная "quote" установлена ​​в ее обратное значение, поэтому установлена ​​в "TRUE".

  2. Затем мы проверяем запятую, И если кавычка установлена ​​в ее обратное значение, то есть если кавычка ИСТИНА, что имеет место, когда мы находимся внутри кавычек.

  3. Мы сократили это с помощью current="", и это то, где я не понимаю: мы все еще между кавычками, поэтому обычно мы не должны сокращать это сейчас! изменить: так и не цитата означает «ложь», а не «противоположность», спасибо!

Код:

def mysplit (string):
    quote = False
    retval = []
    current = ""
    for char in string:
        if char == '"':
            quote = not quote
        elif char == ',' and not quote: #the first coma is still in the quotes, and quote is set to TRUE, so we should not cut current here...
            retval.append(current) 
            current = "" 
        else:
            current += char
    retval.append(current)
    return retval

Ответы [ 6 ]

3 голосов
/ 03 ноября 2011

Вы просматриваете его так, как если бы оба if char == '"' и elif char == ',' and not quote были запущены.

Однако оператор if явно делает так, что будет выполняться только один.

Либо, цитатабудет инвертировано ИЛИ значение current будет обрезано.

В случае, когда текущий символ равен ", будет вызвана логика для инвертирования флага quote.Но логика обрезки строки не будет работать.

В случае, когда текущий символ равен ,, тогда логика инвертирования флага НЕ будет работать, но логика обрезки строки будет работать, еслиquote флаг не установлен.

1 голос
/ 03 ноября 2011

ОК, вы не совсем там!

1. первый символ - это кавычка "" ", поэтому переменная" кавычка "установлена ​​в ее обратное значение, поэтому установите" ИСТИНА ".

хорошо! Поэтому в кавычке было установлено значение, обратное тому, что было ранее. В начале проги оно было ложным, поэтому, когда " видно, оно становится истинным. Но порокнаоборот, если это было Истина, и кавычка видна, она становится ложной.

Другими словами, эта строка программы меняет quote с того, что было до этой строки. Она называется «переключение».

  1. тогда мы проверяем кому, И если кавычка установлена ​​в ее обратное значение, то есть если кавычка ИСТИНА, что имеет место, когда мы находимся внутри кавычек.

Это не совсем верно. not quote означает "только если кавычка ложна". Это не имеет никакого отношения к тому, установлено ли для значение обратного . Нет переменная может быть равна ее собственной инверсии! Это все равно, что сказать X=True and X=False - очевидно ерунда.

quote всегда либо True, либоFalse - и ничего больше!

3. Мы сократили его с помощью current = "", и это то, где я не понимаю: мы все еще между кавычками, поэтому мы должны быть в нормене сокращайте это сейчас!

Так что, надеюсь, вы теперь можете видеть, что вы не окажетесь между кавычками, если достигнете этой строки.not quote гарантирует, что вы не будете заключать в кавычки, потому что not quote действительно означает именно это - не в кавычках!

1 голос
/ 03 ноября 2011

Это не лучший код для разбиения, но он довольно прост

   1 current = ""

   # First you set current to empty string, the following line
   # will loop through the string to be split and pull characters out of it
   # one by one... setting 'char' to be the value of next character

   2 for char in string:

   # the following code will check if the line we are currently inside of the quote
   # if otherwise it will add the current character to the the 'current' variable
   # 

   3     if char == '"':
   4         quote = not quote
   5     elif char == ',' and not quote:
   6         retval.append(current) 

   ### if we see the comma, it will append whatever is accumulated in current to the 
   ### return result.
   ### then you have to reset the value in the current to let the next word accumulate


   7         current = "" #why do we cut current here? 
   8     else:
   9         current += char

   ### after the last char is seen, we still have left over characters in current which
   ### we can just shove into the final result

   10 retval.append(current)
   11 return retval


   Here is an example run:

   Let string be  'a,bbb,ccc

   Step  char  current   retval

    1     a      a        {}
    2     ,               {a}       ### Current is reset
    3     b      b        {a}
    4     b      bb       {a} 
    5     b      bbb      {a}
    6     ,               {a,bbb}   ### Current is reset

   and so on
1 голос
/ 03 ноября 2011

То, на что вы смотрите, является сжатой версией Finite State Machine , используемой большинством программ синтаксического анализа языка.

Давайте посмотрим, не могу ли я это аннотировать:

def mysplit (string):
    # We start out at the beginning of the string NOT in between quotes
    quote = False
    # Hold each element that we split out
    retval = []
    # This variable holds  whatever the current item we're interested in is
    # e.g: If we're in a quote, then it's everything (including commas)
    # otherwise it's every UP UNTIL the next comma
    current = ""
    # Scan the string character by character
    for char in string:
        # We hit a quote, so turn on QUOTE SCANNING MODE!!!
        # If we're in quote scanning mode, turn it off
        if char == '"':
            quote = not quote
        # We hit a comma, and we're not in quote scanning mode
        elif char == ',' and not quote:
            # We got what we want, let's put it in the return value
            # and then reset our current item to nothing so we can prepare for the next item.
            retval.append(current) 
            current = "" 
        else:
            # Nothing special, let's just keep building up our current item
            current += char
    # We're done with all the characters, let's put together whatever we were working on when we ran out of characters
    retval.append(current)
    # Return it!
    return retval
1 голос
/ 03 ноября 2011

current сбрасывается на пустое, потому что в случае, когда вы встретили кавычки ',' и у вас нет "" кавычек, вы должны интерпретировать это как конец "токена".

Это определенно не питон, for char in string заставляет меня съеживаться, и тот, кто написал этот код, должен был использовать регулярное выражение.

1 голос
/ 03 ноября 2011

Инициализирует current пустой строкой, уничтожая все, что могло быть установлено ранее.

Пока вы не в кавычках (т. Е. quote - Ложь), когда вы видите ,, вы достигли конца поля. Все, что вы накопили в current, является содержимым этого поля, поэтому добавьте его к retval и сбросьте current в пустую строку, готовясь к следующему полю.

Тем не менее, похоже, что вы имеете дело с вводом .csv. Есть CSV-модуль , который может решить эту проблему для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...