黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Python將字符串常量轉(zhuǎn)化為變量方法總結(jié)

系統(tǒng) 1901 0

前幾天,我們Python貓交流學(xué)習(xí)群 里的 M 同學(xué)提了個(gè)問題。這個(gè)問題挺有意思,經(jīng)初次討論,我們認(rèn)為它無解。

然而,我認(rèn)為它很有價(jià)值,應(yīng)該繼續(xù)思考怎么解決,所以就在私密的知識(shí)星球上記錄了下來。

萬萬沒想到的是,在第二天,有兩位同學(xué)接連給出了解決方法!

由此,群內(nèi)出現(xiàn)了一輪熱烈的技術(shù)交流。

本文將相關(guān)的內(nèi)容要點(diǎn)作了梳理,并由此引申到更進(jìn)一步的學(xué)習(xí)話題,希望對(duì)你有所幫助。

1、如何動(dòng)態(tài)生成變量名?

M 同學(xué)的問題如下:

打擾一下大家,請(qǐng)教一個(gè)問題,已知 list = ['A', 'B', 'C', 'D'] , 如何才能得到以 list 中元素命名的新列表 A = [], B = [], C = [], D = [] 呢?

簡(jiǎn)單理解,這個(gè)問題的意思是,將字符串內(nèi)容作為其它對(duì)象的變量名。

list 中的元素是字符串,此處的 ‘A'-‘D' 是常量 ,而在要求的結(jié)果中,A-D 是變量 。

如果強(qiáng)行直接將常量當(dāng)做變量使用,它會(huì)報(bào)錯(cuò):

>>> 'A' = []
...SyntaxError: can't assign to literal

報(bào)錯(cuò)中的literal 指的是字面量 ,這是計(jì)算機(jī)科學(xué)中常見的一個(gè)概念,用于表達(dá)源代碼中的固定值。 例如,整數(shù)、浮點(diǎn)數(shù)、字符串等基本類型,就是字面量。

字面量指的就是一個(gè)量本身,可以理解為一種原子性的實(shí)體,當(dāng)然不能再被賦值了。

所以,取出的字符串內(nèi)容,并不能直接用作變量名,需要另想辦法。

有初學(xué)者可能會(huì)想,list[0] = [] 行不行?當(dāng)然不行,因?yàn)闆]有出現(xiàn) A 。那 A = list[0] ,接著 A = [] 呢?那也不行,因?yàn)檫@里的 A 是你憑空定義出來的,而不是從已有條件中生成的。

當(dāng)時(shí),群里只有兩三個(gè)同學(xué)參與了討論,我們沒想到解決辦法。但是,我覺得這個(gè)題目很有意思,值得玩味。

因?yàn)?,如果能解決這個(gè)問題,那就意味著可以不作預(yù)先定義,而是動(dòng)態(tài)地生成變量名,這不僅能減少給變量取名的麻煩,還實(shí)現(xiàn)了自動(dòng)編碼!

可以設(shè)想一下未來,人工智能在編寫代碼的時(shí)候,如果能根據(jù)已知條件,動(dòng)態(tài)生成變量名,那編寫代碼的過程不就順利多了么?(據(jù)說,現(xiàn)在已經(jīng)有人工智能可以編寫代碼了,不知它在取變量名時(shí),是用的什么方法?)

2、辦法總是有的

最近,學(xué)習(xí)群里蒙混進(jìn)來了幾個(gè)打廣告的,為此,我決定提高審核門檻,例如,用群里的問題來作個(gè)考核。

萬萬沒想到的是,第一個(gè)被考核到的 Q 同學(xué),幾乎不假思索地就說出了一個(gè)解決上述問題的思路。而偏偏就是那么巧 ,幾乎在同時(shí),群內(nèi)的 J 同學(xué)給出了另外一個(gè)解決方法(他沒看到群內(nèi)的討論,而是看到了知識(shí)星球的記錄,才知道這個(gè)問題的)。

也就是說,前一晚還以為無解的問題,在第二天竟得到了兩種不同的解決方法!

那么,他們的答案是什么呢?

            
# J 同學(xué)的解答
>>> list1 = ['A', 'B', 'C', 'D']
>>> for i in list1:
>>> globals()[i] = []
>>> A
[]
          

這個(gè)方法通過修改全局命名空間,巧妙地“定義”出了新的變量。globals() 方法取出來的是一個(gè)字典,字符串 ‘A' 是其中一個(gè)鍵值(key),而這個(gè)鍵值恰恰是全局命名空間中的一個(gè)變量,這就實(shí)現(xiàn)了從常量到變量的轉(zhuǎn)化。

在數(shù)據(jù)結(jié)構(gòu)層面上,空列表 [] 作為一個(gè)值(value)跟它的字符串鍵值綁定在一起,而在運(yùn)用層面上,它作為變量?jī)?nèi)容而跟變量名綁定在一起。

看到這個(gè)回答的時(shí)候,我就突然想起來了,上個(gè)月轉(zhuǎn)載過一篇《Python 動(dòng)態(tài)賦值的陷阱》,講的正是動(dòng)態(tài)地進(jìn)行變量賦值 的問題??!我似乎只關(guān)注了 globals() 與 locals() 用法的區(qū)別,卻沒有真正地掌握它們的原初用途。

J 同學(xué)說,他正是看了那篇文章,才學(xué)得了這個(gè)方法。這就有意思了,我分享了一個(gè)自己囫圇吞棗的知識(shí),然后它被 J 同學(xué)吸收掌握,最后反饋回來解決了我的難題。

我真切地感受到了知識(shí)分享的魅力:知識(shí)在流動(dòng)中獲得生命,在碰撞中锃亮色澤。

同時(shí),我也真切地明白了一個(gè)互助的學(xué)習(xí)團(tuán)體的好處:利人者也利己,互助者共同進(jìn)步。

3、動(dòng)態(tài)執(zhí)行代碼的方法

新進(jìn)群的 Q 同學(xué),提供了一個(gè)不同的答案:

            
# Q 同學(xué)的解答
>>> list1 = ['A', 'B', 'C', 'D']
>>> for i in list1:
>>> exec(f"{i} = []")
>>> A
[]
          

他的寫法用到了 Python 3.6 才引入的 f-strings 特性,事實(shí)上,在較低版本中,也是可以實(shí)現(xiàn)的,只需要保證 exec() 方法接收的參數(shù)是包含了變量 i 的字符串即可,例如這樣寫:

            
# 以下代碼可替換上例的第 4 行
exec(i + " = []")
# 或者:
exec("{} = []".format(i))
# 或者:
exec(' '.join([i, '= []']))
          

這幾種寫法的區(qū)別只是字符串拼接法的區(qū)別,關(guān)于如何拼接字符串,以及不同方法之間的區(qū)別,可參看《詳解Python拼接字符串的七種方式》。

Q 同學(xué)這個(gè)答案的核心在于 exec() 方法,它是內(nèi)置的,用途是執(zhí)行儲(chǔ)存在字符串或文件中的代碼段。

它的基礎(chǔ)用法如下:

            
>>> exec('x = 1 + 2')
>>> x
3

# 執(zhí)行代碼段
>>> s = """
>>> x = 10
>>> y = 20
>>> sum = x + y
>>> print(sum)
>>> """
>>> exec(s)
30
          

看完了 exec() 的用法,我們?cè)倩貋砜?Q 同學(xué)的答案。for-循環(huán)中取出來的 i 是字符串,而拼接后的字符串經(jīng)過 exec() 的處理,就獲得了動(dòng)態(tài)編寫代碼的效果。

也就是說,因?yàn)樽址A康膬?nèi)容被當(dāng)做有效代碼而執(zhí)行了,其中的 'A'-'D' 元素,就取得了新的身份,變成了最終的 A-D 變量名。

這個(gè)方法看起來很簡(jiǎn)單啊,可是由于 exec() 方法太生僻了,直到 Q 同學(xué)提出,我們才醒悟過來。

注意:在 Python3 中,exec() 是個(gè)內(nèi)置方法;而在 Python2 中,exec 是個(gè)語句(statement),另外有個(gè) execfile() 方法,兩者相合并,就成了 Python3 中的 exec() 方法。本文使用的是 Python3。

4、總結(jié)

抽象一下最初的問題,它實(shí)際問的是“如何將字符串內(nèi)容作為其它對(duì)象的變量名”,更進(jìn)一步地講是――“如何將常量轉(zhuǎn)化為變量 ”。

使用直接進(jìn)行賦值的靜態(tài)方法,行不通。

兩位同學(xué)提出的方法都是間接的動(dòng)態(tài)方法:一個(gè)是動(dòng)態(tài)地進(jìn)行變量賦值,通過修改命名空間而植入變量;一個(gè)是動(dòng)態(tài)地執(zhí)行代碼,可以說是通過“走后門”的方式,安插了變量。

兩種方法殊途同歸,不管是白貓還是黑貓,它們都抓到了老鼠。

這兩種方法已經(jīng)給我們帶來了很有價(jià)值的啟發(fā),同時(shí),因?yàn)樗鼈儯簝?nèi)小伙伴們更是發(fā)散地討論一些相關(guān)聯(lián)的話題,例如:S 同學(xué)提出了另一種修改命名空間中變量的寫法、L 同學(xué)提到了 eval() 的意義、eval() 與 exec() 的區(qū)別、我查到了為什么要慎用 eval() 、C 與 H 同學(xué)提到了 eval() 的安全用法……

雖然,某些話題無法在群聊中充分展開,但是,這些話題知識(shí)的延展聯(lián)系,大大地豐富了本文開頭的問題,這一個(gè)微小的問題,牽連出來了兩個(gè)大的知識(shí)體系。

最后,真得感謝群內(nèi)的這些愛學(xué)習(xí)的優(yōu)秀的同志們!除了文中提及的,還有一些同學(xué)也做了積極貢獻(xiàn),大家都很給力!


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦?。?!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論