2015-11-06 12 views
4
>>> 'hi'.split()[0] is 'hi' 
    True  
>>> 'hi there'.split()[0] is 'hi' 
    False 
>>> 'hi there again'.split()[0] is 'hi' 
    False 

Моя гипотеза:Идентичность галтель шпагатом раскола()

Первая строка содержит только один элемент в расколе, в то время как две другие имеют более чем один элемент. Я считаю, что хотя примитивы Python, такие как str, хранятся в памяти по значению внутри функции, для упрощения управления памятью будут выполняться отдельные распределения по всем функциям. Я думаю, что split() является одной из этих функций и обычно выделяет новые строки. Но он также обрабатывает краевой случай ввода, который не требует какого-либо разделения (например, 'hi'), где исходная ссылка на строку просто возвращается. Правильно ли мое объяснение?

+0

нет и причина в том, что «есть» означает то же место в памяти это не то же самое, что «==» изменить ваши сравнения с ==, и они будут работать нормально, «is» следует использовать только для сравнения элементов, находящихся в статической памяти, таких как None a True/False – gkusner

ответ

1

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

Выделение объекта Python не работает. Существует не реальная концепция «примитивов», и помимо нескольких вещей, которые компилятор байт-кода делает для слияния констант, неважно, созданы ли два объекта в одной и той же функции или разных функциях.

Существует на самом деле не лучший ответ на этот вопрос, чем указать на источник, так here it is:

Py_LOCAL_INLINE(PyObject *) 
STRINGLIB(split_whitespace)(PyObject* str_obj, 
          const STRINGLIB_CHAR* str, Py_ssize_t str_len, 
          Py_ssize_t maxcount) 
{ 
    ... 
#ifndef STRINGLIB_MUTABLE 
     if (j == 0 && i == str_len && STRINGLIB_CHECK_EXACT(str_obj)) { 
      /* No whitespace in str_obj, so just use it as list[0] */ 
      Py_INCREF(str_obj); 
      PyList_SET_ITEM(list, 0, (PyObject *)str_obj); 
      count++; 
      break; 
     } 

Если он не находит какой-либо пробел для разделения на, он просто повторно исходный объект строки в возвращенном списке. Это просто причуда, как эта функция была написана, и вы не можете зависеть от нее, работающей таким образом в других версиях Python или нестандартных реализациях Python.

+1

, что является отличным ответом - но реальная точка всего этого должна заключаться в том, чтобы указать на очевидное - НЕ ИСПОЛЬЗОВАТЬ ' сравнить строки - используйте '==' – gkusner

+2

@gkusner: Похоже, что вопросник уже это понимает. В вопросе конкретно задается вопрос о стратегии размещения объектов, и он не упоминает о том, что 'x is y' должно быть истинным для равных строк' x' и 'y'. – user2357112

0

Так как я уже сказал в комментарии:

'hi there again'.split()[0] == 'hi' 

>>True 

На самом деле ваш вопрос вроде прибил его - это тождество.

+1

. Вы действительно не ответьте на вопрос о 'split()', почему один элемент будет иметь одинаковое расположение памяти, но более одного элемента не будет. Это потому, что каждая функция имеет свои собственные примитивные распределения? – onepiece

+0

по существу да, область строки хэширована, чтобы сохранить дублирование, поэтому строка Hi хранится только один раз – gkusner

0

Все данные в Python хранятся по ссылке. (A PyObject* в реализации C). Вы обнаружили, что .split() просто вернул self в качестве оптимизации, когда разделитель не был найден. Когда разделитель найден, он должен создавать отдельные строковые объекты для каждой части, и поэтому они являются отдельными объектами.

(В отличие от Java, который имеет совершенно разные типы данных для «примитивов» и «ссылочные типы/класса» и ведет себя по-разному с ними)

+0

Хм, я сейчас изучаю Java и не знаю этого; Это интересно. Хорошее объяснение. – Saroekin

 Смежные вопросы

  • Нет связанных вопросов^_^