Python:输入内容相同但输出内容不同

时间:2018-12-03 08:54:35

标签: python list

我将列表传递给函数并查看输出。当列表经过硬编码后,我得到了预期的输出。但是,当我从字符串构建列表并将具有相同内容的列表传递给函数时,我没有预期的输出。

首次通话:

tech = [ "Django", "Zend", "SQLite", "foo" ]

for tech_item in tech:
    print( test_main( tech_item ) )

第二通电话:

raw_txt = "Django,Zend,SQLite,foo"
tech = raw_txt.split( "," )
# At this point if we print "tech" we have:
# [ "Django", "Zend", "SQLite", "foo" ]

for tech_item in tech:
    print( test_main( tech_item ) )

因此,输入/似乎相同,但输出不同。

当我比较两个列表的内容(重新命名第二个列表:tech2)时,我有:

print( tech[0], tech2[0] ) #Django Django
print( tech[0] == tech2[0] ) #True
print( type(tech[0]), type(tech2[0]) ) #<class 'str'> <class 'str'>
print( len(tech[0]), len(tech2[0]) ) #6 6

我想念什么? 您是否有关于如何查找/解决此问题的线索?

编辑:

第一种情况下的输出:

frameworks
frameworks
SQL
None

第二种情况下的输出:

None
None
None
None

test_main函数

我给了您test_main函数,但恐怕它会使您感到困惑。 因此,“ look_for”每次都相同。但是“ tmp”在两种情况下都是不同的。

def test_main( looking_for ):
    global tmp
    tmp = None

    get_recursively( languages_tech, looking_for )

    return tmp

get_recursively功能

def get_recursively( data, looking_for, last_key="" ):
    if not isinstance( data, (list, dict) ):
        if data is looking_for: #item
            global tmp
            tmp = last_key
    else:
        if isinstance( data, dict ): #Dictionaries
            for key, value in data.items():
                get_recursively( value, looking_for, key )
        else:
            for item in data: #list
                get_recursively( item, looking_for, last_key )

Languages_tech

languages = { "languages": [
"Ruby", "Python", "JavaScript", "ASP.NET", "Java", "C", "C++", "C#", "Swift", "PHP", "Visual Basic", "Bash" ] }

frameworks = { "frameworks" : [
"Django", "Flask", "React", "React Native", "Vue", "Ember", "Meteor", "AngularJS", "Express" , "Laravel", "Symfony", "Zend", "Ruby on Rails" ] }

databases = { "databases" : [
{ "SQL": ["MariaDB", "MySQL", "SQLite", "PostgreSQL", "Oracle", "MSSQL Server"] },
{ "NoSQL": ["Cassandra", "CouchDB", "MongoDB", "Neo4j", "OrientDB", "Redis", "Elasticsearch"] },
{ "ORM Framework": [ "SQLAlchemy", "Django ORM" ] } ] }

languages_tech = { "languages_tech": [ languages, frameworks, databases ]  }

1 个答案:

答案 0 :(得分:1)

简短回答

get_recursively()函数中的以下行是错误的

if data is looking_for:

改为使用此

if data == looking_for:

长答案

a is b仅在truea具有相同的b的情况下才能得出id。也就是说,

(a is b) == (id(a) == id(b))

默认情况下,为字符串文字分配相同的ID。例如,

>>> a = "Trebuchet"
>>> b = "Trebuchet"
>>> id(a), id(b)
(4416391792, 4416391792)

请注意,两个id均为4416391792。这同样适用于list(即使列表不是同一对象,因此也没有相同的id)。

>>> a = ["Trebuchet", "Catapult", "Ballista"]
>>> b = ["Trebuchet", "Catapult", "Ballista"]
>>> id(a), id(b)
(4416392200, 4416861640)

>>> id(a[0]), id(b[0])          
(4416391792, 4416391792)

请注意,4416391792与上一个示例完全相同。这将显示字符串如何指向相同的对象。

但是当您使用str.split()函数时...

>>> a = "Trebuchet;Catapult;Ballista".split(';')
>>> b = ["Trebuchet", "Catapult", "Ballista"]
>>> id(a[0]), id(b[0])          
(4416392240, 4416391792)

id(b[0])保留在4416391792,我们之前已经看到过。但是现在,请注意str.split()创建一个新的字符串对象,列表中的id = 4416392240

这是data is looking_for为何为假的原理。

当然,is有其优点。例如,我们执行a is None而不执行a == Noneread more)。但是,区分何时使用is和何时使用==至关重要。在比较文字的值(例如字符串,列表或元组)时,使用==


进一步阅读:

Why does comparing strings in Python using either '==' or 'is' sometimes produce a different result?

Another example where variables can have congruent string literals but different ids.