簡體   English   中英

python和mysql對於類似命令的結果是不同的

[英]Results are different between python and mysql for similar command

我當時使用python創建字典,但是隨着我的數據變大,我開始出現內存錯誤,所以我以為我會節省內存,只是將數據寫到數據庫中,但是結果卻不一樣。 我認為這與defaultdict的行為有關(但我不確定)。

這是有效的python代碼(它基本上建立了一個值表):

from collections import defaultdict
data = [2,5,10]
target_sum = 100
# T[x, i] is True if 'x' can be solved
# by a linear combination of data[:i+1]
T = defaultdict(bool)           # all values are False by default
T[0, 0] = True                # base case

for i, x in enumerate(data):    # i is index, x is data[i]
    for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
        for c in range(s / x + 1):  
            if T[s - c * x, i]:
                T[s, i+1] = True

#check the python dict results
count = 0
for x in T:
    if T[x] == True:
        print x, ':', T[x]
        count = count +1

print 'total count is ', count
#False is 152 and True is 250.  Total is: 402

結果是一個很大的值表(您可以在注釋中看到細分。這是我想要的正確結果),但是當我更改第一個for語句的最后一行以添加到數據庫而不是本地dict時,結果有所不同。

這是有問題的我修改后的代碼:

cursor = conn.cursor ()
cursor = conn.cursor ()
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
    CREATE TABLE data_table
    (
      value     CHAR(80),
      state BOOL
    )
  """)
#with database
for i, x in enumerate(data):    # i is index, x is data[i]
    for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
        for c in range(s / x + 1):  
            cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
            if cursor.rowcount == 0:
                #print 'nothing found, adding'
                cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', False)""" % ([s - c * x, i]))
            elif cursor.rowcount == 1:
                cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % ([s - c * x, i]))
                #print 'record updated'
    conn.commit()

#False is 17 and True is 286. Total is: 303

總結一下(如果您不想運行代碼),defaultdict在查詢某些內容時會創建一個錯誤的條目(在這種情況下, if T[s - c * x, i]:以便復制此功能我對值進行mysql查找,如果不存在則創建它,如果存在則將其設置為true。 我非常懷疑我無法正確復制功能

我唯一想的另一件事是python將結果顯示為(222, 0) : False 222,0 (222, 0) : False但是mysql正在[222,0]不確定是否會有所作為。

您的兩個示例未更新相同的密鑰:

# First example
if T[s - c * x, i]:
    T[s, i+1] = True
    # Key is (s, i+1)

# Second example
elif cursor.rowcount == 1:
    cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % ([s - c * x, i]))
    # Key is (s - c * x, i)

IMO僅將True案例存儲在數據庫中會更有意義,這可能會使您的程序更簡單。 否則,您還需要檢查數據庫中是否存在(s, i+1)如果存在則將其更新為True,否則將其創建為新行。

PS我也錯過了將(0, 0)為True的命令。 在創建數據庫之后,這不應該放在插入內容中嗎?

更新 :在您的代碼中還發現了另一個問題:select命令僅檢查行是否存在 ,而不是行的值。 為了正確地復制您的第一個示例,您的代碼應為:

cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', True)""" % ([0, 0]))
conn.commit()
# Inserted the (0,0) case
for i, x in enumerate(data):
    for s in range(target_sum + 1):
        for c in range(s / x + 1):  
            cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
            if cursor.rowcount == 0:
                cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', False)""" % ([s - c * x, i]))
            elif cursor.rowcount == 1:
                (value, state) = cursor.fetchone() # Gets the state
                if state: # equivalent to your if in the first example
                    insertOrUpdate(conn, [s, i+1])
    conn.commit()

更改的行已注釋。

更新2 :這還不夠...(正如我所說,如果只存儲True值,則要簡單得多)。 為了便於閱讀,將零件移到了if內部:

def insertOrUpdate(conn, key):
    cursor.execute(""" SELECT value, state FROM data_table WHERE value='%s' """ % key)
        if cursor.rowcount == 0:
            # Insert as True if not exists
            cursor.execute (""" INSERT INTO data_table (value, state) VALUES ('%s', True)""" % key)
        elif cursor.rowcount == 1:
            (value, state) = cursor.fetchone()
            if !state:
                # Update as True, if it was False
                cursor.execute (""" UPDATE data_table SET state=True WHERE value = '%s'""" % key)

更新3:相比之下,僅存儲True值就可以使程序變得更簡單。 它還使用更少的磁盤空間,花費更少的時間,並且表現得更像defaultdict。

cursor = conn.cursor ()
cursor.execute ("DROP TABLE IF EXISTS data_table")
cursor.execute ("""
    CREATE TABLE data_table(
        value     CHAR(80)
    )
""")

cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [0, 0])
conn.commit()

for i, x in enumerate(data):    # i is index, x is data[i]
    for s in range(target_sum + 1): #set the range of one higher than sum to include sum itself
        for c in range(s / x + 1):  
            cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % ([s - c * x, i]))
            if cursor.rowcount == 1:
                cursor.execute(""" SELECT value FROM data_table WHERE value='%s' """ % [s, i+1])
                if cursor.rowcount == 0:
                    cursor.execute (""" INSERT INTO data_table (value) VALUES ('%s')""" % [s, i+1])
    conn.commit()

暫無
暫無

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

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