Ir para o conteúdo
PsySc0rpi0n

[Dúvidas] - Dicionários

Mensagens Recomendadas

PsySc0rpi0n

Quando temos um dicionário simples, apenas com keys e valores:

dic1 = {key1:value1, key2:value2........}

e fazemos por exemplo:

dic1[key1] = 'value_x'

Porque é que o valor da key1 desaparece do dict1 e é como se fosse substituído pelo novo valor? A intenção era adicionar valores à mesma chave!!

(que borracheira escrever metade bem e metade mal)

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

PsySc0rpi0n, corrige o post para que a tua dúvida esteja escrita em português, de acordo com a linguagem utilizada neste fórum... e depois falamos novamente.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Então agora a questão que se coloca é a seguinte:

>>> x = 5
>>> x
5
>>> x = 6
>>> x

Qual será o output do interpretador? será 6, 11 ou [5, 6]?

Editado por pwseo
Adicionada outra opção estranha

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

É 6, claramente, mas 'x' não é um dic! Ou seja, até pode ter lógica quando sabemos como funcionam os dics mas estamos a comparar coisas diferentes que eu não sei se funcionam da mesma maneira! 'x' e dics!

De qualquer forma acho que já percebi! Estamos simplesmente a substituir o value de uma determinada key!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

De qualquer forma acho que já percebi! Estamos simplesmente a substituir o value de uma determinada key!

É precisamente isso. Funciona (quase) como se fosse uma variável.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Mais uma dúvida

Quero adicionar valores a uma lista dentro de um dicionário...

O seguinte code está a fazer replace e eu ainda não percebi porquê!

#!/usr/bin/python
# -*- coding: UTF-8 -*-

#create a mapping of state to abbreviation
states = { 
       'Minho':'MNH',
       'Trás-os-Montes':'ToMT',
       'Douro-Litoral':'DRLTL',
       'Beira-Litoral':'BRLTL',
       'Beira-Alta':'BRALT',
       'Beira-Baixa':'BRBXA',
       'Estremadura':'ETRMD',
       'Ribatejo':'RBTJ',
       'Alto-Alentejo':'ALALTJ',
       'Baixo-Alentejo':'BXALTJ',
       'Algarve':'ALGRV'
       }

#create a basic set of states and some cities in them
cities = { 
       'MNH':[],
       'ToMT':[],
       'BRLTL':[],
       'BRALT':[],
       'BRBXA':[],
       'ETRMD':[],
       'RBJT':[],
       'ALALTJ':[],
       'BXALTJ':[],
       'ALGRV':[]
       }

def add_to_dic():
   check = False
   while not check:
       cit = raw_input('Enter a city name: ')
       sta = raw_input('Enter the state name: ')
       try:
           cities[sta].append(cit)
           check = True
       except KeyError:
           print '{} is not a valid state!'.format(sta)
           check = False
add_to_dic()
print cities

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

De cada vez que executas o código, os dicionários são inicializados para o seu estado vazio. Para fazeres o que pretendes tens duas hipóteses:

  1. Implementar algum tipo de persistência (guardar e ler os valores de um ficheiro)
  2. Pedir dados ao utilizador várias vezes durante a mesma execução -- mas aqui perdes tudo quando o programa terminar

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys

#create a mapping of state to abbreviation
states = {
        'Minho':'MNH',
        'Trás-os-Montes':'ToMT',
        'Douro-Litoral':'DRLTL',
        'Beira-Litoral':'BRLTL',
        'Beira-Alta':'BRALT',
        'Beira-Baixa':'BRBXA',
        'Estremadura':'ETRMD',
        'Ribatejo':'RBTJ',
        'Alto-Alentejo':'ALALTJ',
        'Baixo-Alentejo':'BXALTJ',
        'Algarve':'ALGRV'
        }

#create a basic set of states and some cities in them
cities = {
        'MNH':[],
        'ToMT':[],
        'BRLTL':[],
        'BRALT':[],
        'BRBXA':[],
        'ETRMD':[],
        'RBJT':[],
        'ALALTJ':[],
        'BXALTJ':[],
        'ALGRV':[]
        }

def add_to_dic():
    cit = ''
    sta = ''
    check = False
    while not cit == 'e' or not cit == 'E' or not sta == 'e' or not sta == 'E':
        print 'Check: {}'.format(check)
        while not check:
            cit = raw_input('Enter a city name: ')
            if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
                sys.exit()
            sta = raw_input('Enter the state name: ')
            if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
                sys.exit()
            try:
                cities[sta].append(cit)
                check = False
                print cities
            except KeyError:
                print '{} is not a valid state!'.format(sta)
                check = True
                print 'Mile1'
add_to_dic()

Obviamente pode ser melhorado em várias frentes, provavelmente com ferramentas que desconheço mas para já é como está!

Ainda assim, tem um bug...

Quando se insere um 'e' ou um 'E' na variável 'cit', o script não termina logo. Só termina após o estado ser colocado na variável 'sta'!

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Code corrigido e melhorado!

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import sys 

#create a mapping of state to abbreviation
states = { 
        'Minho':'MNH',
        'Trás-os-Montes':'ToMT',
        'Douro-Litoral':'DRLTL',
        'Beira-Litoral':'BRLTL',
        'Beira-Alta':'BRALT',
        'Beira-Baixa':'BRBXA',
        'Estremadura':'ETRMD',
        'Ribatejo':'RBTJ',
        'Alto-Alentejo':'ALALTJ',
        'Baixo-Alentejo':'BXALTJ',
        'Algarve':'ALGRV'
        }

#create a basic set of states and some cities in them
cities = { 
        'MNH':[],
        'ToMT':[],
        'BRLTL':[],
        'BRALT':[],
        'BRBXA':[],
        'ETRMD':[],
        'RBJT':[],
        'ALALTJ':[],
        'BXALTJ':[],
        'ALGRV':[]
        }

def add_to_dic():
    cit = ''
    sta = ''
    while not cit == 'e' or not cit == 'E' or not sta == 'e' or not sta == 'E':
        cit = raw_input('Enter a city name: ')
        if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
            sys.exit()
        sta = raw_input('Enter the state name: ')
        if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
            sys.exit()
        try:
            cities[sta].append(cit)
            print cities
        except KeyError:
            print '{} is not a valid state!'.format(sta)

add_to_dic()

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from sys import argv, exit

if argv == '':
   print 'Usage python dics1.py <path-to-file_name>'
   sys.exit()

script, filename = argv
print filename
def open_file(filename):
   try:
       txt = open(filename)
       print "The file {} was successfully opened!".format(filename)
       return txt
   except IOError, OSError:
       print "An erroroccured while openning {} file!".format(filename)
       sys.exit()

def write_to_file (filename, file_hand):
   try:
       file_hand.write()
   except IOError, OSError:
       print "An error occured when writing to {}!".format(filename)
       sys.exit()

#create a mapping of state to abbreviation
states = {
       'Minho':'MNH',
       'Trás-os-Montes':'ToMT',
       'Douro-Litoral':'DRLTL',
       'Beira-Litoral':'BRLTL',
       'Beira-Alta':'BRALT',
       'Beira-Baixa':'BRBXA',
       'Estremadura':'ETRMD',
       'Ribatejo':'RBTJ',
       'Alto-Alentejo':'ALALTJ',
       'Baixo-Alentejo':'BXALTJ',
       'Algarve':'ALGRV'
       }

#create a basic set of states and some cities in them
cities = {
       'MNH':[],
       'ToMT':[],
       'BRLTL':[],
       'BRALT':[],
       'BRBXA':[],
       'ETRMD':[],
       'RBJT':[],
       'ALALTJ':[],
       'BXALTJ':[],
       'ALGRV':[]
       }

def add_to_dic():
   cit = ''
   sta = ''
   while not cit == 'e' or not cit == 'E' or not sta == 'e' or not sta == 'E':
       cit = raw_input('Enter a city name: ')
       if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
           sys.exit()
       sta = raw_input('Enter the state name: ')
       if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
           sys.exit()
       try:
           cities[sta].append(cit)
           print cities
       except KeyError:
           print '{} is not a valid state!'.format(sta)

add_to_dic()
file_handler = open_file(filename)
write_to_file(filename, file_handler)
file_handler.close()

Ok, eu tenho este código onde defini funções para abrir um file, e guardar o conteúdo em memória para o mesmo file!

Mas não sei ainda como funciona ali os argumentos da linha de comandos que se passam para o programa.

tenho visto exemplos onde têm:

script, filename = argv

Podem explicar como funciona o argv??? Já percebi que está ali a ser feito um "descompactamento" da variável argv, que penso que seja uma list! Mas por exemplo, se eu passar 2 ou mais argumentos na linha de comandos para o programa, a variável argv guarda-os todos? E para aceder a todos os argumentos, basta percorrer a lista? É isso? E quantas mais variáveis tiver à esquerda do '=', serã lá guardados os argumentos presentes em argv e por "ordem de chegada"??? É isto?

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

A função que escreve para o ficheiro não está a funcionar.

O meu código está assim:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from sys import argv, exit

if not len(argv) == 2 :
   print 'Usage python dics1.py <path-to-file_name>'
   exit()

script, filename = argv
print "Script: {0}\nFilename: {1}\n".format(script, filename)

#############-Function to open a file-#####################
def open_file(filename):
   try:
       txt = open(filename, 'a+')
       print "The file {} was successfully opened!".format(filename)
       return txt
   except IOError, OSError:
       print "An error occured while openning {} file!".format(filename)
       exit()

############-Function to write data to a file-###############
def write_to_file (data, file_hand, filenam):
   try:
       file_hand.write(data)
       print "Data successfully written into {}!".format(filenam)
   except IOError, OSError:
       print "An error occured when writing to {}!".format(filenam)
       exit()

###########-Create a map for state abbreviation-########
states = {
       'Minho':'MNH',
       'Trás-os-Montes':'ToMT',
       'Douro-Litoral':'DRLTL',
       'Beira-Litoral':'BRLTL',
       'Beira-Alta':'BRALT',
       'Beira-Baixa':'BRBXA',
       'Estremadura':'ETRMD',
       'Ribatejo':'RBTJ',
       'Alto-Alentejo':'ALALTJ',
       'Baixo-Alentejo':'BXALTJ',
       'Algarve':'ALGRV'
       }

####-create a basic set of states and some cities in them-#####
cities = {
       'MNH':[],
       'ToMT':[],
       'BRLTL':[],
       'BRALT':[],
       'BRBXA':[],
       'ETRMD':[],
       'RBJT':[],
       'ALALTJ':[],
       'BXALTJ':[],
       'ALGRV':[]
       }

################-Add data to the dictionary-##################
def add_to_dic():
   cit = ''
   sta = ''
   while not cit == 'e' or not cit == 'E' or not sta == 'e' or not sta == 'E':
       cit = raw_input('Enter a city name: ')
       if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
           return
       sta = raw_input('Enter the state name: ')
       if cit == 'e' or cit == 'E' or sta == 'e' or sta == 'E':
           return
       try:
           cities[sta].append(cit)
           """print cities"""
           for x in cities:
               for y in cities[x]:
                   print "{0} : {1}".format(x, cities[y])
       except KeyError:
           print '{} is not a valid state!'.format(sta)

file_handler = open_file(filename)
add_to_dic()
write_to_file(cities, file_handler, filename)
file_handler.close()

O erro é o seguinte:

Traceback (most recent call last):
 File "dics1.py", line 84, in <module>
   write_to_file(cities, file_handler, filename)
 File "dics1.py", line 26, in write_to_file
   file_hand.write(data)
TypeError: expected a character buffer object

Edited;

Code actualizado... Agora o programa diz sempre que o estado que eu insiro não existe!

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Removi alguns blocos de verificações para ficar o code mais limpo já que não é necessário para já todas as verificações que tinha:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from sys import argv, exit

if not len(argv) == 2 :
   print 'Usage python dics1.py <path-to-file_name>'
   exit()

script, filename = argv
print "Script: {0}\nFilename: {1}\n".format(script, filename)

#############-Function to open a file-#####################
def open_file(filename):
   txt = open(filename, 'a+')
   print "The file {} was successfully opened!".format(filename)
   return txt

############-Function to write data to a file-###############
def write_to_file (data, file_hand, filenam):
   file_hand.write(str(data))
   print "Data successfully written into {}!".format(filenam)
   exit()

###########-Create a map for state abbreviation-########
states = {
       'MNH'   : 'Minho',
       'ToMT'  : 'Trás-os-Montes',
       'DRLTL' : 'Douro-Litoral',
       'BRLTL' : 'Beira-Litoral',
       'BRALT' : 'Beira-Alta',
       'BRBXA' : 'Beira-Baixa',
       'ETRMD' : 'Estremadura',
       'RBTJ'  : 'Ribatejo',
       'ALALTJ': 'Alto-Alentejo',
       'BXALTJ': 'Baixo-Alentejo',
       'ALGRV' : 'Algarve'
        }

####-create a basic set of states and some cities in them-#####
cities = {
       'MNH':[],
       'ToMT':[],
       'BRLTL':[],
       'BRALT':[],
       'BRBXA':[],
       'ETRMD':[],
       'RBJT':[],
       'ALALTJ':[],
       'BXALTJ':[],
       'ALGRV':[]
       }

################-Add data to the dictionary-##################
def add_to_dic():
   cit = ''
   sta = ''
   while not cit == 'e' or not cit == 'E' or not sta == 'e' or not sta == 'E':
       cit = raw_input('Enter a city name: ')
       if cit == 'e' or cit == 'E':
           return
       sta = raw_input('Enter the state name: ')
       if sta == 'e' or sta == 'E':
           return
       if sta in states:
           cities[sta].append(cit)
           for x in cities:
               print "---{}---".format(x)
               for y in cities[x]:
                   print "{}".format(y)
       else:
           print '{} is not a valid state!'.format(sta)

file_handler = open_file(filename)
add_to_dic()
write_to_file(cities, file_handler, filename)
file_handler.close()

Edited;

Código actualizado...

Agora está mais funcional que antes e já não dá erros!

Agora a questão é conseguir carregar o ficheiro que já tem dados e adicionar novos dados sem perder os antigos e gravar os dados actualizados no ficheiro!

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

PsySc0rpi0n,

Será uma boa oportunidade para dares uma olhadela no módulo json. É um formato muito utilizado para aquilo que pretendes, e tens muito bom suporte para ele na linguagem Python.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

@pwseo

Consigo melhorar este menu em termos de código? Simplificar, rearranjar o código, eliminar linhas que estejam ali redundantes?

from sys import exit

def menus():
    print 'Main menu:\n'
    print '\t[O]pen File\n'
    print '\t[s]ave File\n'
    print '\t[A]dd data\n'
    print '\t[E]xit\n'

menus()
option = raw_input('Choose an option:\n')
while (option != 'E'):
    while (option != 'O' and option != 'S' and option != 'A' and option != 'E'):
        print "<{}> is an invalid option! Try again:\n".format(option)
        option = raw_input('Choose an option:\n')

    if option == 'O':
        print 'Opening file!!!\n'
    elif option == 'S':
        print 'Saving file!!!\n'
    elif option == 'A':
        print 'Adding data!!!\n'
    else:
        print 'Unkown error!!!\n'
        exit();
    menus()
    option = raw_input('Choose an option:\n')

E ainda, como se limpa a consola em python???

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

PsySc0rpi0n,

Podes utilizar uma lista/dicionário para associar cada opção a uma tecla e a uma função a executar, em vez de teres isso como uma série de if..elif..else.

A própria impressão do menu seria dinâmica: bastaria imprimir cada opção que estivesse disponível.

EDIT:

E ainda, como se limpa a consola em python???

Da mesma forma que o fazes em qualquer outra linguagem. Isso depende do terminal e sistema operativo que estás a utilizar, e não da linguagem em si (embora algumas possam abstrair isso)

Editado por pwseo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

@pwseo

Podes utilizar uma lista/dicionário para associar cada opção a uma tecla e a uma função a executar

Isso seria algo do género:

actions = {'O':['Open File', open_file()], 'S':['Save file', save_file()], 'A':['Add item', add_to_dic()], 'E':['Exit', exit()]}

ou não tem nada a ver???

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

Sim, poderia ser algo desse género, mas com uma alteração: não podes colocar os () no final dos nomes das funções a invocar. Tu queres apenas referir o nome da função e não invocá-la e colocar o seu resultado na lista (que é o que acontece se deixares o código dessa forma).

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Assim:

ctions = {'O':['Open File', open_file], 'S':['Save file', save_file], 'A':['Add item', add_to_dic], 'E':['Exit', exit]}

E depois diz lá como é que se usa este dicionário quando o user escolhe uma das opções?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Vou deixar-te pensar um pouco nisso e dar palpites, porque é isso que nos faz avançar.

Se eu percebi o objectivo, quando o user inserir uma das opções possíveis, a respectiva função será chamada, certo?

Mas como é que isso vai funcionar se no dicionário, o nome das funções não tem os parêntesis?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Fiz o seguinte a título de exemplo:

from sys import exit
from string import upper

def open_file():
    print "Open file success!\n"

def save_to_file():
    print "Save to file success!\n"

def add_data():
    print "Add data success!\n"


actions = {'O':['Open file', open_file()],
           'S':['Save file', save_to_file],
           'A':['Add data',add_data],
           'E':['Exit',exit]
          }

print actions['O'][1]
print actions['S'][1]

O output é o seguinte:

Open file success!

None
<function save_to_file at 0x7f06b52d1c08>

Não sei se é suposto o nome das funções no dicionário estar mesmo sem os parêntesis curvos mas não estou a ver como se poder fazer isto... Pelo menos para já!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pwseo

O teu exemplo tem alguns problemas... Mas repara neste exemplo que te dou e tenta perceber o que aconteceu. Depois compara com o teu código e tenta perceber o que tens que alterar:

>>> def bla():
...     print 'bla!!!'
... 
>>> bla
<function bla at 0x7f51bb440578>
>>> bla()
bla!!!
>>> meh = bla
>>> meh
<function bla at 0x7f51bb440578>
>>> meh()
bla!!!

Editado por pwseo
Exemplo expandido

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Resultado, para já:

from sys import exit
from string import upper

def open_file():
   print "Open file success!\n"

def save_to_file():
   print "Save to file success!\n"

def add_data():
   print "Add data success!\n"


actions = {'O':['Open file', open_file],
          'S':['Save file', save_to_file],
          'A':['Add data',add_data],
          'E':['Exit',exit]
         }

opt = ''
while opt != 'E':
   opt = upper(raw_input('Select an option: '))
   if opt in actions:
       actions[opt][1]()
   else:
       print "Invalid option! Try again: "

Está bom ou pode ficar melhor ainda?

Editado por PsySc0rpi0n

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
PsySc0rpi0n

Neste momento o code está assim:

from sys import exit
from string import upper

def open_file():
    print "Open file success!\n"

def save_to_file():
    print "Save to file success!\n"

def add_data():
    print "Add data success!\n"

menus = [
        '[O]pen File',
        '[s]ave File',
        '[A]dd data',
        '[E]xit'
        ]

actions = {
          'O':['Open file', open_file],
          'S':['Save file', save_to_file],
          'A':['Add data',add_data],
          'E':['Exit',exit]
          }

print '\x1b[3;J\x1b[H\x1b[2J'
opt = ''
while opt != 'E':
    for men in menus:
        print '{}'.format(men)
    opt = upper(raw_input('Select an option: '))
    if opt in actions:
        actions[opt][1]()
        print '\x1b[3;J\x1b[H\x1b[2J'
    else:
        print "Invalid option! Try again: "
        print '\x1b[3;J\x1b[H\x1b[2J'

Pode ser melhorado, @pwseo?

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.