簡體   English   中英

在一行中聲明和循環變量

[英]Declaring and Looping over a variable in one line

只是為了好玩,我試圖將一個編程問題壓縮成一行。 我知道這通常是一種不好的做法,但這是一個有趣的挑戰,我正在尋求您的幫助。

我有一段代碼聲明變量,在第二行中循環遍歷在第一行中創建的列表,直到找不到數字為止。 最后它返回那個值。

編程題如下。 給定一個句子,將每個字符轉換為它的 ascii 表示形式。 然后將該ascii值轉換為二進制(如果二進制數少於8位,則用0填充剩余的空格),並將這些數字組合成一個字符串。 從數字 0 開始,將其轉換為二進制並檢查它是否在字符串中。 如果是,請將數字加一並再次檢查。 返回字符串中最后一個連續的二進制數。 前任)

字符串 = “0000010”

字符串中的 0:加 1

字符串中的 1:加 1

字符串中的 10:加 1

11 不在字符串中:最后一個連續的二進制數是 10 2 =2 10 返回 2

你可以在下面看到我的代碼

def findLastBinary(s: str):
    string, n = ''.join(['0'*(10-len(bin(ord(char))))+bin(ord(char))[2:] for char in s]), 0
    while bin(n)[2:] in string: n+=1
    return n-1

如果我能將 return 語句和循環也合並到一行中,那就太好了。

編輯

修復了代碼(現在應該可以工作了)。 同樣在下面,您將看到一個示例測試用例。 希望這有助於回答這個問題。

示例測試用例

輸入:

s="玫瑰與荊棘"

下面您將看到我的代碼遵循的步驟以獲得正確的答案(顯然更具可讀性)

按以下順序組織成列:

Character-Ascii-Binary ascii值的表示:

R - 82 - 01010010

Ø - 111 - 01101111

小號 - 115 - 01110011

等等

請記住,如果二進制數少於 8 位,則應在數字的開頭添加零,直到它是 8 位。

然后將每個二進制 integer 連接成一個字符串(我添加空格只是為了便於閱讀):

01010010 01101111 01110011 01100101 01110011 00100000 01100001 01101110 01100100 00100000 01110100 01101000 01101111 01110101110 11101011

現在我們從二進制數 0 開始,檢查它是否在字符串中。 所以我們繼續看 1。1 在字符串中,所以我們繼續看 10。10 在字符串中。 所以我們繼續,直到我們發現二進制字符串 11111 不在我們的字符串中。 11111 2 =31 10 由於 31 是第一個十進制數不在字符串中的數字,因此我們返回最后一個十進制數在字符串中的數字:即 31-1=30。 30 是 function 應該返回的。

function 可以這樣定義 function,感謝@treuss 的觀察:

def largest_binary_number(sentence: str):
    return int(''.join([bin(ord(char))[2:].zfill(8) for char in sentence]), 2)

但假設問題是“找到大於 1000 的最小基數 10 integer,其二進制表示在字符串中”。 然后我們有這樣的事情:

def find(sentence: str):
    return list(iter(lambda: globals().__setitem__('_c', globals().get('_c', 1000-1) + 1) or bin(globals().get('_c'))[2:] in ''.join([bin(ord(c))[2:].zfill(8) for c in sentence]), True)) is type or globals().get('_c')

讓我們把它分成四個部分:

  1. globals().__setitem__('_c', globals().get('_c', 1000-1) + 1) - 初始化並遞增一個計數器
  2. ... or bin(globals().get('_c'))[2:] in ''.join([bin(ord(c))[2:].zfill(8) for c in sentence]) - 檢查計數器的二進制表示是否在句子的二進制表示中
  3. list(iter(lambda: ..., True)) - 使用黑魔法內聯 while 循環
  4. ... is type or globals().get('_c') - 獲取滿足我們條件的計數器的最終值
第 1 部分: globals().__setitem__('_c', globals().get('_c', 1000-1) + 1)

由於我們被限制在一行中做所有事情,我們沒有定義變量的奢侈。 這就是globals的用武之地:我們可以使用__setitem__get方法存儲和使用任意變量作為字典條目。 這里我們將計數器變量命名為_c ,調用get初始化並獲取值,然后立即將其遞增 1 並使用__setitem__保存該值。 現在我們有一個計數器變量。

第 2 部分: ... or bin(globals().get('_c'))[2:] in ''.join([bin(ord(c))[2:].zfill(8) for c in sentence])

bin(globals().get('_c'))[2:]將計數器轉換為二進制並刪除0b前綴。 ''.join([bin(ord(c))[2:].zfill(8) for c in sentence])和以前一樣,將輸入的句子轉換為二進制。 我們用in來檢查二進制計數器是否是一個 substring 的二進制語句。 因為來自第 1 部分的__setitem__調用返回None ,我們在這里使用or來忽略它並執行這部分。

第 3 部分: list(iter(lambda: ..., True))

這是面包和黃油,允許我們執行內聯迭代。 iter通常傳遞一個可迭代對象來創建和迭代器,但它實際上有第二種形式,它采用兩個 arguments:一個可調用對象和一個哨兵。 當迭代使用這種雙參數形式創建的迭代器時,可調用對象會被連續調用,直到它返回標記值(注意無限循環)。 所以我們定義了一個 lambda function 當條件滿足時返回True ,並將哨兵設置為True 最后我們使用list構造函數開始迭代。

第 4 部分: ... is type or globals().get('_c')

一旦list構造函數完成迭代,我們需要獲取並返回計數器的最終值。 我們跟隨list(...) with is type來創建一個始終計算為False的表達式,然后在這一行的末尾用or globals().get('_c')鏈接它以返回計數器。 瞧!

第 5 部分:

當然,我們之前擁有的是雙線。

find = lambda sentence: list(iter(lambda: globals().__setitem__('_c', globals().get('_c', 1000-1) + 1) or bin(globals().get('_c'))[2:] in ''.join([bin(ord(c))[2:].zfill(8) for c in sentence]), True)) is type or globals().get('_c')

現在我們有一個單線。


注意:事后看來,也許海象:=可以用來制作計數器,而不必每次都調用globals() 但是,由於某些原因,用locals變量替換globals不起作用。

注2:使用這些技術,我們可以制作滿足各種條件的單線。


更新:這是另一個使用海象的版本

find = lambda sentence: (_c := {'v': 1000-1}) and list(iter(lambda: _c.__setitem__('v', _c['v'] + 1) or bin(_c['v'])[2:] in ''.join([bin(ord(c))[2:].zfill(8) for c in sentence]), True)) is type or _c['v']

我們在頂層初始化計數器,並在其他地方簡單地使用_c 請注意它是一個 dict 而不是 int,因為不能在內部 lambda 中分配外部變量(但可以改變外部變量)。

你可以使用; 語法,但我不確定在這種情況下這是否是一個足夠好的解決方案,因為您正在嘗試這是一個挑戰。 它的語法是這樣的<statement1>;<statement2>

所以你的代碼看起來像這樣:

def largest_binary_number(sentence: str):
    binary_string, n = ''.join(['0'*(10-bin(ord(char)))+bin(ord(char))[2:] for char in sentence]),0; while bin(n)[2:] in binary_string: n+=1; return n-1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM