Forum Coders' city Strona Gwna Coders' city
Nasza pasja to programowanie!
 

 PomocPomoc   SzukajSzukaj   UytkownicyUytkownicy   GrupyGrupy  RejestracjaRejestracja 
Archiwum starego forum + teoria    RSS & Panel/SideBar
 ProfilProfil   Zaloguj si, by sprawdzi wiadomociZaloguj si, by sprawdzi wiadomoci   ZalogujZaloguj 

Potrzebuj szybkiej odpowiedzi na moje pytanie... Zasady

Python: unhashable type list



 
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> Python
Zobacz poprzedni temat :: Zobacz nastpny temat  
Autor Wiadomo
korenld
Go





PostWysany: Pon Pa 06, 2014 7:03 pm  OP    Temat postu: Python: unhashable type list Odpowiedz z cytatem Pisownia

Kod:

from sys import *

tokens = []
symbols = {}

def open_file(filename):
    data = open(filename, "r").read()
    data += "<EOF>"
    return data

def lex(filecontents):
    tok = ""
    state = 0
    isexpr = 0
    varstarted = 0
    var = ""
    string = ""
    expr = ""
    n = ""
    filecontents = list(filecontents)
    for char in filecontents:
        tok += char
        if tok == " ":
            if state == 0:
                tok = ""
            else:
                tok = " "
        elif tok == "\n" or tok == "<EOF>":
            if expr != "" and isexpr == 1:
                tokens.append("EXPR:" + expr)
                expr = ""
            elif expr != "" and isexpr == 0:
                tokens.append("NUM:" + expr)
                expr = ""
            elif var != "":
                tokens.append("VAR:" + var)
                var = ""
                varstarted = 0
            tok = ""
        elif tok == "=" and state == 0:
            if var != "":
                tokens.append("VAR:" + var)
                var = ""
                varstarted = 0
            tokens.append("EQUALS")
            tok = ""
        elif tok == "#" and state == 0:
            varstarted = 1
            var += tok
            tok = ""
        elif varstarted == 1:
            if tok == "<" or tok == ">":
                if var != "":
                    tokens.append("VAR:" + var)
                    var = ""
                    varstarted = 0
                tok = ""
            var += tok
            tok = ""
        elif tok == "PRINT" or tok == "print":
            tokens.append("PRINT")
            tok = ""
        elif tok == "0" or tok == "1" or tok == "2" or tok == "3" or tok == "4" or tok == "5" or tok == "6" or tok == "7" or tok == "8" or tok == "9":
            expr += tok
            tok = ""
        elif tok == "+" or tok == "-" or tok == "*" or tok == "/" or tok == "(" or tok == ")":
            isexpr = 1
            expr += tok
            tok = ""
        elif tok == "\"":
            if state == 0:
                state = 1
            elif state == 1:
                tokens.append("STRING:" + string + "\"")
                string = ""
                state = 0
                tok = ""
        elif state == 1:
            string += tok
            tok = ""
    return tokens

def evalExpression(expr):
    return eval(expr)

def doPRINT(doPRINT):
    if doPRINT[0:6] == "STRING":
        doPRINT = doPRINT[8:]
        doPRINT = doPRINT[:-1]
    elif doPRINT[0:3] == "NUM":
        doPRINT = doPRINT[4:]
    elif doPRINT[0:4] == "EXPR":
        doPRINT = evalExpression(doPRINT[5:])
    print(doPRINT)

def doASSIGN(varname, varvalue):
    symbols[varname[4:]] = varvalue

def getVARIABLE(varname):
    varname = varname[4:]
    if varname in symbols:
        return symbols[varname]
    else:
        return "Undefined Variable"

def parse(toks):
    i = 0
    while(i < len(toks)):
        if toks[i] + " " + toks[i+1][0:6] == "PRINT STRING" or toks[i] + " " + toks[i+1][0:3] == "PRINT NUM" or toks[i] + " " + toks[i+1][0:4] == "PRINT EXPR" or toks[i] + " " + toks[i+1][0:3] == "PRINT VAR":
            if toks[i+1][0:6] == "STRING":
                doPRINT(toks[i+1])
            elif toks[i+1][0:3] == "NUM":
                doPRINT(toks[i+1])
            elif toks[i+1][0:4] == "EXPR":
                doPRINT(toks[i+1])
            elif toks[i+1][0:3] == "VAR":
                doPRINT(getVARIABLE([i+1]))
            i += 2
        elif toks[i][0:3] + " " + toks[i+1] + " " + toks[i+2][0:6] == "VAR EQUALS STRING" or toks[i][0:3] + " " + toks[i+1] + " " + toks[i+2][0:3] == "VAR EQUALS NUM" or toks[i][0:3] + " " + toks[i+1] + " " + toks[i+2][0:4] == "VAR EQUALS EXPR":
            if toks[i+2][0:6] == "STRING":
                doASSIGN(toks[i],toks[i+2])
            elif toks[i+2][0:3] == "NUM":
                doASSIGN(toks[i],toks[i+2])
            elif toks[i+2][0:4] == "EXPR":
                doASSIGN(toks[i],"NUM:" + str(evalExpression(toks[i+2][5:])))
            i+=3

def run():
    data = open_file(argv[1])
    toks = lex(data)
    parse(toks)

run()



Co jest le?
To jest bd: unhashable type list
Powrt do gry
biernik



Doczy: 06 Wrz 2008
Posty: 1148
Skd: 6359'39''N 2238'11''W

PostWysany: Sob Pa 11, 2014 8:15 pm      Temat postu: Odpowiedz z cytatem Pisownia

Nie odpalaem kodu, ale pewnie chodzi o to:
Kod:

def doASSIGN(varname, varvalue):
    symbols[varname[4:]] = varvalue


Co tutaj wida:
varname[4:] to jest slice listy, czyli rwnie lista.
symbols to jest dict - czyli hash table.
Klucz takiej tablicy musi by haszowalny, lista nie jest haszowalna.
Prawdopodobnie, chciae zrobi co takiego:
Kod:

var_key = ''.join(varname[4:])
symbols[var_key] = varvalue


A jeeli na prawd chcesz mie co listowatego jako klucz w sowniku, to moesz zrobi tak:
Kod:

var_key = tuple(varname[4:])
symbols[var_key] = varvalue
# zadziaa, bo tuple jest haszowalna (bo jest immutable w przeciwiestwie to listy)



I tak jeszcze kilka uwag:

Kod:

from sys import *


niezalecane, raczej importuj to co uywasz
albo zaimportuj sys i uywaj penej cieki. np. sys.something
Kod:

def open_file(filename):
    data = open(filename, "r").read()
    ...


Dobrym zwyczajem jest zamykanie pliku po jego otwarciu.
Pomimo tego, e tutaj masz tymczasowy obiekt,
a GC powinien zamkn plik kiedy sprzta obiekt, to na prawd nie masz pewnoci kiedy to si stanie.
Czyli raczej co takiego:
Kod:

with open(filename, 'r') as my_file:
    data = my_file.read()



Takie rzeczy:
Kod:

if tok == "<" or tok == ">":
elif tok == "PRINT" or tok == "print":
# a takie ju na pewno:
elif tok == "0" or tok == "1" or tok == "2" or tok == "3" or tok == "4" or tok == "5" or tok == "6" or tok == "7" or tok == "8" or tok == "9":


Czytelniej zapiszesz:
Kod:

if tok in('<', '>')

elif tok in('PRINT', 'print')
# albo:
elif tok.lower() == 'print'

elif tok in('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
# albo:
elif tok.isdigit()



Kod:

def doPRINT(doPRINT):


To generalnie nie jest dobry pomys.

Kod:

if doPRINT[0:6] == "STRING":
    doPRINT = doPRINT[8:]
    doPRINT = doPRINT[:-1]


Tutaj druga linja jest bez sensu, bo zaraz trzecia nadpisuje doPRINT.
Mona by si te przyczepi, e jeste niekonsekwenty w plasterkowaniu.
Jak plasterkujesz do koca to robisz: lista[start:]
A jak robisz od pocztku to robisz: lista[0:end], zamiast po prostu lista[:end]


Kod:

i = 0
while(i < len(toks)):


Takie co jest uznawanie za "niepytoniczne" (cokolwiek to znaczy), prawie herezja :).
Ptle w pytonie s troch inne ni w C, jeeli potrzebujesz przejecha po czym iterowalnym, to tak:
Kod:

for token in toks:
    ...
# lub jeeli potrzebujesz te indeksu, to:
for idx, token in enumerate(toks)



Pozdrwka.

_________________
I like cheese.
Powrt do gry
Zobacz profil autora Wylij prywatn wiadomo
Wywietl posty z ostatnich:   
Odpowiedz do tematu    Forum Coders' city Strona Gwna -> Python Wszystkie czasy w strefie CET (Europa)

Strona 1 z 1

 
Skocz do:  
Moesz pisa nowe tematy
Moesz odpowiada w tematach
Nie moesz zmienia swoich postw
Nie moesz usuwa swoich postw
Nie moesz gosowa w ankietach
Moesz dodawa zaczniki na tym forum
Moesz pobiera pliki z tego forum




Debug: strone wygenerowano w 0.18926 sekund, zapytan = 11
contact

| Darmowe programy i porady Jelcyna | Tansze zakupy w Helionie | MS Office Blog |