Quando o código a seguir, que acrescenta uma cláusula else a um comando for, é executado, o que é exibido?
for n in range(4): if n == 9: breakelse: print("done")print(n)
Apenas 3 é exibido, e done não aparece
Apenas done é exibido, e 3 não aparece
3 e done são exibidos nessa ordem
done e 3 são exibidos nessa ordem
RespostaD. done e 3 são exibidos nessa ordem
Uma cláusula else (else 節) acrescentada a um comando for é executada quando o laço termina sem ser interrompido por break. Não há 9 em range(4), então o break nunca acontece e, depois de percorrer o laço até o fim, o print do else é executado, fazendo done aparecer. Em seguida, print(n) exibe o valor que ficou em n depois de sair do laço, o último valor, 3. Inverter a ordem leva a uma forma em que 3 vem primeiro; entender erroneamente que o else é sempre pulado ao fim de um laço leva a uma forma sem done; e deixar passar que n permanece depois de sair do laço leva a uma forma sem 3.
Questão 2 | break e else
Verifique como a cláusula else é tratada quando se sai de um laço com break. Qual é a saída do código a seguir?
for c in "abc": if c == "b": break print(c)else: print("no break")
a b c e no break são todos exibidos
a e no break são exibidos nessa ordem
a e b, os dois, são exibidos nessa ordem
a é exibido, e no break não é exibido
RespostaD. a é exibido, e no break não é exibido
Na primeira passagem, c é a, então print(c) é executado e a é exibido. Na segunda passagem, c se torna b, e o break interrompe o laço. A cláusula else (else 節) de um comando for só é executada quando o laço termina sem ser interrompido por break, então aqui ela é pulada e no break não aparece. Supor que o else sempre é executado quando o laço termina leva a uma forma em que no break também aparece; ler erroneamente como se print(c) viesse antes do break leva a uma forma em que b também aparece; e deixar passar o próprio break leva a uma forma em que a b c são todos exibidos.
Questão 3 | else mesmo quando vazio
Considere o que acontece com a cláusula else de um comando for quando aquilo que ele percorre está vazio. Qual é o resultado da execução do código a seguir?
items = []for it in items: print(it)else: print("finished")
A cláusula else é ignorada e ocorre um TypeError
Como há 0 iterações, ocorre um StopIteration
Sai do laço sem exibir absolutamente nada
finished é exibido apenas uma vez
RespostaD. finished é exibido apenas uma vez
A condição para a cláusula else (else 節) de um comando for ser executada é "o laço ter terminado sem ser interrompido por break", e não "ter iterado pelo menos uma vez". Como items está vazio, o corpo nunca é executado, mas, como também não houve break, o else é executado normalmente, e finished é exibido. Se você pensar que o else também é pulado quando está vazio, obterá uma forma sem nada exibido. Passar uma lista vazia para um comando for é, em si, uma sintaxe correta, então não lança exceção, e não ocorre nem TypeError nem StopIteration.
Questão 4 | while/else
Considere acrescentar uma cláusula else a um comando while e sair dele no meio do caminho. Qual é a saída do código a seguir?
n = 5while n > 0: n -= 1 if n == 2: breakelse: print("loop ended")print(n)
0 é exibido, e loop ended não é exibido
2 é exibido, e loop ended não é exibido
loop ended e 2 são exibidos nessa ordem
loop ended e 0 são exibidos nessa ordem
RespostaB. 2 é exibido, e loop ended não é exibido
n diminui de 1 em 1 a partir de 5, passando por 4 e 3, e sai com break quando chega a 2. A cláusula else (else 節) de um comando while, assim como a de um comando for, só é executada quando o laço termina sem ser interrompido por break, então aqui ela é pulada e loop ended não aparece. O que resta é apenas o 2 de print(n). Pensar que o else sempre é executado leva a uma forma em que loop ended também aparece, e deixar passar o break e ler erroneamente como se o laço continuasse até a condição se tornar falsa leva a uma forma em que n se torna 0.
Questão 5 | continue
Quando o código a seguir, que mistura continue e break em um único laço, é executado, qual lista é exibida no final?
out = []for i in range(6): if i == 3: continue if i == 5: break out.append(i)print(out)
[0, 1, 2, 4, 5]
[0, 1, 2, 3]
[0, 1, 2, 4]
[0, 1, 2, 3, 4]
RespostaC. [0, 1, 2, 4]
Quando i é 0, 1 ou 2, os dois comandos if são ultrapassados e o valor é acrescentado. Quando i é 3, o continue entra em ação, pulando o restante daquela passagem, ou seja, o append. Quando i é 4, ele é acrescentado novamente e, quando i é 5, o break interrompe o laço, então nenhum append acontece. Portanto, o resultado é [0, 1, 2, 4]. Pensar que a passagem com break também é adicionada leva a uma forma que vai até 5, e tratar o continue como pass leva a uma forma em que o 3 permanece.
Questão 6 | range em ordem inversa
Considere a ordem produzida quando range recebe um passo negativo. Qual é a saída do código a seguir?
print(list(range(10, 0, -3)))
[9, 6, 3, 0]
[7, 4, 1, -2]
[10, 7, 4, 1, 0]
[10, 7, 4, 1]
RespostaD. [10, 7, 4, 1]
range(start, stop, step) começa em start, avança de step em step e para antes de chegar a stop. Aqui, subtraindo 3 repetidamente a partir de 10, a sequência avança como 10, 7, 4, 1, e o valor seguinte, -2, não é adotado por ser 0 ou menor. Como o valor de parada 0 não é incluído, a sequência não termina com 0. Entender erroneamente que start não é incluído leva a uma forma que começa em 7, e pensar que a contagem começa um passo antes de start leva a uma forma que começa em 9. O ponto de stop não ser incluído é o mesmo de quando o passo (刻み幅) é positivo.
Questão 7 | O tipo de range
Qual das alternativas a seguir descreve corretamente o objeto obtido ao chamar a função embutida range?
Um objeto do tipo gerador que fica vazio depois de ser percorrido uma vez
Um objeto do tipo range que se torna uma lista quando passado para list()
Um objeto do tipo tupla cujos elementos não podem ser substituídos
Um objeto do tipo lista que é exibido como está, com colchetes
RespostaB. Um objeto do tipo range que se torna uma lista quando passado para list()
O que range retorna é um objeto do tipo range, que calcula o inteiro necessário toda vez que é solicitado. Ele não guarda todos os elementos de antemão como uma lista, então não consome memória mesmo para um intervalo grande. Para ver o conteúdo enfileirado, passe-o por list(). type(range(3)) é range, e não list nem tuple, e simplesmente exibi-lo não mostra a sequência de elementos, mas sim range(0, 3). Também não é um gerador (generator), já que não é de uso único e pode ser percorrido quantas vezes se quiser. Observe que a propriedade de poder ser lido por índice e de não permitir a substituição de elementos é a mesma de uma tupla (タプル), então só essa propriedade não basta para distingui-lo de uma tupla.
Questão 8 | Avaliação em curto-circuito
Verifique o que os operadores lógicos or e and retornam. Qual é a saída do código a seguir?
print([] or 0 or "z")print(1 and 0 and 2)
True e False são exibidos nessa ordem
False e 0 são exibidos nessa ordem
z e 0 são exibidos nessa ordem
z e 2 são exibidos nessa ordem
RespostaC. z e 0 são exibidos nessa ordem
or avalia da esquerda para a direita e retorna, como está, o primeiro valor que se mostra verdadeiro. Como uma lista vazia e 0 são ambos falsos, o último, "z", é retornado. and, ao contrário, retorna o primeiro valor que se mostra falso: 1 é verdadeiro, então no valor seguinte, 0, o resultado falso fica definido e 0 é retornado, e o 2 mais à direita nunca é avaliado. O que é retornado não é um valor booleano (真偽値), mas o valor no ponto em que a avaliação parou, então True ou False nunca aparecem. and só retorna o 2 mais à direita quando tudo pelo caminho é verdadeiro.
Questão 9 | Comparação encadeada
Quando o código a seguir, que combina uma comparação encadeada com uma expressão ternária, é executado, o que é exibido?
x = 3print(1 < x < 5)print("yes" if x % 2 else "no")
True e yes são exibidos nessa ordem
True e no são exibidos nessa ordem
False e no são exibidos nessa ordem
False e yes são exibidos nessa ordem
RespostaA. True e yes são exibidos nessa ordem
1 < x < 5 significa o mesmo que (1 < x) and (x < 5); se x é 3, ambas as condições valem, então o resultado é True. Uma expressão ternária (三項演算子) é organizada como valor-se-verdadeiro if condição else valor-se-falso, e aqui a condição é x % 2, ou seja, 1. Em Python, qualquer inteiro diferente de zero é tratado como verdadeiro, então yes é escolhido. Ler erroneamente a comparação encadeada (連鎖比較) como se ela se agrupasse a partir do final, como em 1 < (x < 5), leva à resposta errada de que x < 5 é True, ou seja, 1, e então 1 < 1 é False. Além disso, pensar em 1 como falso leva a escolher no.
Questão 10 | O papel de pass
Qual das alternativas a seguir descreve corretamente o comando pass do Python?
Indica interromper o próprio laço e sair dele
Indica não fazer nada, em um lugar onde um bloco é sintaticamente obrigatório
Indica pular o restante de um laço e passar para a próxima iteração
Indica que a função terminou de executar e retorna um valor a quem a chamou
RespostaB. Indica não fazer nada, em um lugar onde um bloco é sintaticamente obrigatório
Como o Python representa um bloco com indentação, não é possível escrever um bloco vazio. pass é o que preenche esse lugar, nos casos em que você pretende escrever depois o conteúdo de uma classe ou função, ou quando deliberadamente quer não fazer nada quando uma condição é satisfeita. Ele não tem nenhum efeito sobre o fluxo de execução. Passar para a próxima iteração é continue, interromper o laço é break, e retornar um valor a quem chamou é return — cada um tem um papel diferente do de pass.
Questão 11 | enumerate
Quando o código a seguir, que passa um segundo argumento para enumerate, é executado, o que aparece na tela?
for i, name in enumerate(["gu", "choki", "pa"], 1): print(i, name)
São exibidas as 3 linhas 1 gu / 2 choki / 3 pa
São exibidas as 3 linhas 0 gu / 1 choki / 2 pa
São exibidas as 3 linhas gu 1 / choki 2 / pa 3
São exibidas apenas as 2 linhas 1 gu / 2 choki
RespostaA. São exibidas as 3 linhas 1 gu / 2 choki / 3 pa
enumerate retorna tuplas (número, elemento) em ordem, e o segundo argumento, start, permite especificar o valor a partir do qual a contagem começa. Aqui, 1 é passado, então os números se tornam 1, 2, 3. Confundir isso com o padrão de começar em 0 quando start é omitido leva a uma forma que começa em 0. Como a tupla (タプル) retornada tem o número primeiro e o elemento depois, a ordem de print(i, name) também segue essa ordem, então o nome nunca sai primeiro. Os 3 elementos são todos extraídos, então a saída também não é cortada depois de 2 linhas.
Questão 12 | O comprimento de zip
Duas listas de comprimentos diferentes foram passadas para zip. Qual é o resultado da execução do código a seguir?
print(list(zip([1, 2, 3], [10, 20])))
[(1, 10), (2, 20)]
[(1, 10), (2, 20), (3,)]
[(1, 10), (2, 20), (3, 0)]
[(10, 1), (20, 2)]
RespostaA. [(1, 10), (2, 20)]
zip tira um elemento de cada vez de cada um dos iteráveis (反復可能なもの) que recebe, forma pares com eles e para assim que o mais curto se esgota. Aqui, a segunda lista tem 2 elementos, então apenas 2 pares são formados, e o 3 que sobra é descartado silenciosamente. Não ocorre erro, nem a falta é preenchida com 0, nem é criada uma tupla com apenas um elemento. O conteúdo de cada par segue a ordem em que foram passados, então eles não são trocados, como 10 e 1 seriam.
Questão 13 | Desfazendo pares com zip
Dados em pares foram passados novamente para zip com um asterisco. Qual é a saída do código a seguir?
RespostaB. (1, 2, 3) é exibido, seguido de ('a', 'b', 'c')
Colocar um asterisco (星印) passa cada par dentro da lista para zip como um argumento separado. Ou seja, é o mesmo que chamar zip((1, 'a'), (2, 'b'), (3, 'c')), e os primeiros elementos de cada par são reunidos, assim como os segundos, separando-se nas duas sequências (1, 2, 3) e ('a', 'b', 'c'). Esse é o truque padrão para transformar dados em pares de volta nas duas sequências originais, e passá-los duas vezes por zip faz voltar ao original. O que é retornado são tuplas, e não listas, então o resultado não sai na forma com colchetes. Se você esquecer o asterisco e escrever zip(pairs), cada par em si é passado como um único argumento, e você obtém uma forma enfileirada como tuplas de um elemento, como ((1, 'a'),).
Questão 14 | dict e zip
Um dicionário é construído a partir de uma sequência de chaves e uma sequência de valores. Qual é o resultado da execução do código a seguir?
zip(keys, vals) retorna tuplas (chave, valor) em ordem, e dict() recebe essa sequência de pares e constrói um dicionário (辞書) a partir dela. O primeiro item de cada par se torna a chave e o segundo o valor, então o resultado não sai com os números como chaves. Como passa por dict(), também não fica como uma lista de tuplas. Mesmo sendo exibido com chaves { }, o que faz algo ser um dicionário é ter pares unidos por dois-pontos; ter apenas valores enfileirados seria um conjunto (集合).
Questão 15 | Compreensão de lista
Quando o código a seguir, que usa uma compreensão de lista, é executado, qual lista é exibida?
print([n * n for n in range(1, 5)])
[0, 1, 4, 9]
[2, 4, 6, 8]
[1, 4, 9, 16]
[1, 4, 9, 16, 25]
RespostaC. [1, 4, 9, 16]
range(1, 5) retorna 1, 2, 3, 4; o valor de parada 5 que foi especificado não é incluído. Elevar cada um ao quadrado dá 1, 4, 9, 16. Supor que range começa em 0 leva a uma sequência que começa em 0, e entender erroneamente que stop é incluído leva a uma sequência que vai até 25. Ler n * n erroneamente como n * 2 leva a uma sequência que aumenta de 2 em 2. Vale a pena criar o hábito de ler uma compreensão (内包表記) como a avaliação da expressão mais à esquerda para cada elemento, construindo uma nova lista com os resultados.
Questão 16 | Compreensão de dicionário
Execute uma compreensão que tem dois-pontos dentro de chaves. Qual é a saída do código a seguir?
words = ["sun", "moon"]print({w: len(w) for w in words})
{'sun': 3, 'moon': 4}
[('sun', 3), ('moon', 4)]
{3: 'sun', 4: 'moon'}
{'sun', 'moon', 3, 4}
RespostaA. {'sun': 3, 'moon': 4}
Uma compreensão com dois-pontos dentro de chaves é uma compreensão de dicionário (辞書内包表記), em que o lado esquerdo dos dois-pontos se torna a chave e o lado direito, o valor. Aqui, ela produz um dicionário com cada palavra como chave e sua quantidade de caracteres como valor. Ler a chave e o valor trocados daria um dicionário com a quantidade de caracteres como chave. Envolvê-la em colchetes daria uma lista de tuplas, mas aqui são chaves, então isso não acontece. Sem dois-pontos, seria uma compreensão de conjunto e sairia apenas como uma exibição de valores enfileirados, mas, como há dois-pontos, o resultado é um dicionário.
Questão 17 | O tipo vindo dos parênteses
Algo que parece uma compreensão foi envolvido em parênteses. Que tipo é exibido quando o código a seguir é executado?
g = (n for n in range(3))print(type(g))
<class 'range'>
<class 'list'>
<class 'generator'>
<class 'tuple'>
RespostaC. <class 'generator'>
Não existe em Python algo como uma compreensão de tupla, e essa forma, envolvida em parênteses, torna-se uma expressão geradora (ジェネレータ式). Seu tipo é generator; em vez de criar todos os valores de antemão, ela os calcula um de cada vez conforme são solicitados, então economiza memória, mas, como é um iterador (イテレータ), esgota-se depois de ser usada uma vez. Quando você quiser uma tupla, envolva-a com tuple(). Escrevê-la com colchetes a transforma em uma compreensão de lista, resultando em list, e atribuir range(3) diretamente resulta em range. tuple não é obtido com essa forma de escrita.
Questão 18 | Compreensão de conjunto
Conte o número de elementos do contêiner criado por uma compreensão de conjunto. Qual é a saída do código a seguir?
print(len({n % 4 for n in range(10)}))
3 é exibido
0 é exibido
10 é exibido
4 é exibido
RespostaD. 4 é exibido
Cada valor de range(10) dividido por 4 deixa resto 0, 1, 2, 3, 0, 1, 2, 3, 0, 1. Uma compreensão com chaves e sem dois-pontos é uma compreensão de conjunto (集合内包表記), então os valores duplicados são reunidos em um só, e o que resta são os 4 valores distintos, 0, 1, 2, 3. Deixar passar que as duplicatas desaparecem e simplesmente contar a quantidade de valores dá 10. Deixar passar que o 0 está entre os restos e contar apenas 1, 2, 3 dá 3. 0 é o valor obtido se você entender erroneamente que a compreensão não produz nada, mas, desde que ela percorra range(10), o conteúdo nunca fica vazio. A ordem de exibição de um conjunto não é fixa, então conferir pelo número de elementos é o caminho seguro.
Questão 19 | Uma compreensão aninhada
Considere a ordem quando duas cláusulas for são enfileiradas em uma compreensão. Qual é o resultado da execução do código a seguir?
Quando uma compreensão tem duas cláusulas for enfileiradas, a escrita à esquerda se torna o laço externo. Essa é exatamente a mesma ordem de quando se escrevem dois comandos for comuns aninhados: x fica fixo em 1 enquanto y percorre a e b, e então x se torna 2 e o mesmo se repete. Ler a cláusula for da direita como a externa leva a uma ordem em que x varia primeiro. O conteúdo de cada par segue a ordem escrita na expressão, (x, y), então a letra nunca vem primeiro.
Questão 20 | O argumento start
Qual das alternativas a seguir descreve corretamente o argumento start, o segundo argumento da função embutida enumerate?
Especifica o número a partir do qual a contagem começa; omitindo-o, conta-se a partir de 0
Especifica a partir de qual elemento começar a extrair; omitindo-o, começa-se do início
Especifica quantos pular a cada vez; omitindo-o, avança-se de um em um
Especifica até quantos contar; omitindo-o, conta-se até o fim
RespostaA. Especifica o número a partir do qual a contagem começa; omitindo-o, conta-se a partir de 0
O segundo argumento de enumerate, start, apenas decide a partir de qual número a numeração começa. O padrão é 0, então passar 1 dá uma numeração sequencial amigável para pessoas. Só muda a forma como os números são atribuídos; o ponto crucial é que o intervalo e a quantidade dos elementos extraídos não mudam. Ele não tem o efeito de limitar ou pular a contagem, nem desloca a posição inicial da extração. Todas essas descrições se referem a outras ferramentas, como o fatiamento (スライス).
Questão 21 | O valor de retorno de sort
O valor de retorno do método sort de uma lista foi guardado em uma variável. Qual é a saída do código a seguir?
RespostaD. None e [3, 5, 9] são exibidos nessa ordem
sort é um método que ordena uma lista no próprio lugar (その場で), e seu valor de retorno (戻り値) é None. Assim, result guarda None, e o resultado ordenado fica em nums. Se você supuser que uma nova lista ordenada é retornada, obterá uma forma em que result guarda uma lista. Deixar passar que sort altera a lista original leva a uma forma em que nums permanece na ordem original. Quando você quiser a lista ordenada mantendo a original, use a função embutida sorted.
Questão 22 | A diferença em relação a sorted
Qual das alternativas a seguir descreve corretamente a diferença entre o método sort de uma lista e a função embutida sorted?
sort retorna uma nova lista, e sorted ordena no próprio lugar e retorna None
sort ordena no próprio lugar e retorna None, e sorted retorna uma nova lista
Ambos retornam uma nova lista, e nenhuma das listas originais muda
Ambos ordenam no próprio lugar e também retornam a lista ordenada
RespostaB. sort ordena no próprio lugar e retorna None, e sorted retorna uma nova lista
sort é um método de lista e ordena a própria lista, retornando None como valor de retorno. sorted é uma função embutida (組み込み関数) e retorna uma nova lista ordenada, sem alterar em nada a ordem original. A escolha depende de você querer ou não manter o original. Trocar os papéis dos dois leva a uma explicação em que sort retorna uma nova lista. Pender para um lado ou para o outro quanto a ser destrutivo (破壊的) leva a uma explicação em que ambos ordenam no próprio lugar, ou em que nenhum altera o original. Observe que sorted também aceita um iterável que não seja lista, e seu resultado é sempre uma lista.
Questão 23 | A diferença em relação a append
Compare duas formas de acrescentar uma lista a outra. Qual é a saída do código a seguir?
a = [1, 2]a.append([3, 4])b = [1, 2]b.extend([3, 4])print(a, b)
[1, 2, [3, 4]] [1, 2, [3, 4]]
[1, 2, 3, 4] [1, 2, [3, 4]]
[1, 2, 3, 4] [1, 2, 3, 4]
[1, 2, [3, 4]] [1, 2, 3, 4]
RespostaD. [1, 2, [3, 4]] [1, 2, 3, 4]
append acrescenta seu argumento ao final como um único elemento inteiro, então, se você passar uma lista, ela fica aninhada (入れ子) e o comprimento aumenta em 1. extend acrescenta, um de cada vez, os valores obtidos ao percorrer seu argumento, então o conteúdo é desempacotado e o comprimento aumenta em 2. Trocar os dois papéis inverte os resultados de a e b. Supor que ambos fazem a mesma coisa leva a uma forma em que ambos ficam aninhados ou a uma forma em que ambos ficam planos. Os dois métodos também têm None como valor de retorno, então vale a pena lembrar de não guardar o resultado em uma variável.
Questão 24 | Cópia rasa
Uma lista aninhada foi duplicada com uma fatia, e a parte interna foi reescrita. Qual é o resultado da execução do código a seguir?
A duplicação por fatiamento é uma cópia rasa (浅いコピー): a lista externa é criada de novo, mas os elementos dentro dela são compartilhados com os mesmos objetos do original. copy1[0] e orig[0] apontam para a mesma lista, então fazer append nela também aparece no lado original. Se você supuser que ela está completamente separada, obterá uma forma em que o original não muda. Apenas a primeira lista interna foi reescrita, então a alteração não se estende ao elemento seguinte e, como nada foi acrescentado à lista externa, o 9 também não acaba enfileirado na lista externa. Para separar até as partes internas, use copy.deepcopy.
Questão 25 | Cópia profunda
Compare cópia profunda e cópia rasa em um único trecho de código. Como fica base depois da execução?
copy.deepcopy duplica tudo até o conteúdo aninhado, então d[0] se torna uma lista separada de base[0], e fazer append nela não atinge base. Já s é uma cópia rasa (浅いコピー), então s[1] e base[1] são a mesma lista, e fazer append nela aparece também em base. Assim, apenas o elemento de trás é estendido. Supor que ambos atingem base leva a uma forma em que as duas listas internas são estendidas, e supor que nenhum atinge leva a uma forma inalterada. Confundir cópia profunda (深いコピー) com cópia rasa leva a uma forma em que apenas o elemento da frente é estendido.
Questão 26 | Uma armadilha da multiplicação
Tentou-se construir uma tabela bidimensional com multiplicação de listas. Qual é o resultado da execução do código a seguir?
grid = [[0] * 3] * 2grid[0][1] = 5print(grid)
[[0, 0, 0], [0, 5, 0]]
[[5, 0, 0], [5, 0, 0]]
[[0, 5, 0], [0, 0, 0]]
[[0, 5, 0], [0, 5, 0]]
RespostaD. [[0, 5, 0], [0, 5, 0]]
A multiplicação externa não cria novas linhas; ela apenas enfileira duas referências (参照) para a mesma lista. grid[0] e grid[1] são o mesmo objeto, então reescrever a posição de índice 1 em uma delas aparece como a mesma posição mudando também na outra. Se você pensar que as linhas são independentes, obterá uma forma em que apenas uma linha muda. Como a posição reescrita é a de índice 1, o resultado também não é uma forma em que a primeira posição se torna 5. Para tornar cada linha independente, escreva [[0] * 3 for _ in range(2)].
Questão 27 | Uma tupla de um elemento
Compare o tipo de um valor apenas envolvido em parênteses com o de um valor que tem uma vírgula no final. Qual é a saída do código a seguir?
x = (7)y = (7,)print(type(x).__name__, type(y).__name__)
int e int são exibidos nessa ordem
tuple e tuple são exibidos nessa ordem
tuple e int são exibidos nessa ordem
int e tuple são exibidos nessa ordem
RespostaD. int e tuple são exibidos nessa ordem
O que define uma tupla (タプル) não são os parênteses, mas a vírgula. (7) é apenas um inteiro envolvido em parênteses para indicar a precedência do cálculo, então seu tipo é int, e só (7,), com uma vírgula no final, se torna uma tupla de um elemento. Se você supuser que envolver algo em parênteses o torna uma tupla, obterá uma forma em que ambos se tornam tuple; confundir os dois leva a uma forma com a ordem invertida ou a uma forma em que ambos são int. Observe que a tupla vazia é uma exceção e é escrita como (), sem vírgula.
Questão 28 | O conteúdo de uma tupla
Tentou-se acrescentar um elemento a uma lista colocada dentro de uma tupla. Qual é o resultado da execução do código a seguir?
t = (1, [2, 3], 4)t[1].append(5)print(t)
Um TypeError é lançado
(1, [2, 3], 4, 5)
(1, [2, 3, 5], 4)
(1, [2, 3], 4)
RespostaC. (1, [2, 3, 5], 4)
O que uma tupla congela é para qual objeto cada posição aponta, e não o conteúdo daquilo para que aponta. t[1] é uma lista, e essa lista em si é mutável (ミュータブル), então é possível fazer append nela. Escrever algo como t[1] = [], que atribui à própria posição da tupla, lançaria TypeError, mas aqui nenhuma posição está sendo substituída. Como aquilo a que se acrescentou está dentro da lista, o comprimento da tupla nem aumenta, nem o conteúdo permanece completamente inalterado.
Questão 29 | Atribuição a fatias
Uma lista de comprimento diferente foi atribuída a uma fatia de uma lista. Qual é a saída do código a seguir?
x = [1, 2, 3, 4, 5]x[1:3] = [9]print(x)
[1, 9, 4, 5]
[1, 9, 3, 4, 5]
[1, 9, 9, 4, 5]
[1, 2, 9, 4, 5]
RespostaA. [1, 9, 4, 5]
Atribuir a uma fatia é uma operação que substitui todo o intervalo especificado pelo conteúdo do lado direito. x[1:3] se refere aos 2 elementos 2 e 3, então eles são substituídos pelo único elemento 9, e o comprimento total diminui de 5 para 4. Se você pensar que apenas um elemento é substituído, obterá uma forma em que o comprimento continua 5, e, se pensar que o lado direito é esticado para caber na largura, obterá uma forma em que dois 9 aparecem enfileirados. Deslocar o início do intervalo em uma posição ao ler leva a uma forma em que o 2 permanece. O fato de a largura do lado esquerdo e o comprimento do lado direito poderem ser diferentes é a característica da atribuição a fatias (スライス代入).
Questão 30 | Inserção e remoção
Uma atribuição a uma fatia de largura zero e um del são executados um após o outro. Qual é o resultado da execução do código a seguir?
y = [1, 2, 3]y[1:1] = [7, 8]del y[0]print(y)
[7, 8, 3]
[1, 7, 8, 3]
[7, 8, 2, 3]
[2, 3, 7, 8]
RespostaC. [7, 8, 2, 3]
y[1:1] é um intervalo de largura zero, então uma atribuição a ele se torna uma inserção (挿入) sem nenhuma remoção, e a lista se torna [1, 7, 8, 2, 3]. O del y[0] seguinte remove o 1 inicial, deixando [7, 8, 2, 3]. Se você ler como se um dos elementos originais também desaparecesse durante a inserção, obterá a forma 7 8 3, e, se pensar que del remove outra posição, obterá uma forma em que o 1 inicial permanece. Ler erroneamente como se os valores fossem acrescentados ao final leva a uma forma em que 2 e 3 vêm primeiro. Também vale a pena ter em mente que del é um comando, então não tem valor de retorno, e remove sem extrair o valor.
Questão 31 | O valor padrão de get
Uma chave que não está no dicionário foi consultada com get. O que é exibido quando o código a seguir é executado?
d = {"a": 1, "b": 2}print(d.get("z"), d.get("z", 0))
None e 0 são exibidos nessa ordem
Um KeyError é lançado na primeira
None e None são exibidos nessa ordem
0 e 0 são exibidos nessa ordem
RespostaA. None e 0 são exibidos nessa ordem
get não lança exceção quando a chave não existe; ele retorna None se o segundo argumento for omitido, ou o valor dado, se for informado. Assim, o primeiro é None e o segundo é 0. Se você pensar que 0 é retornado mesmo sem o segundo argumento, obterá ambos como 0 e, se pensar que o segundo argumento é ignorado, obterá ambos como None. Escrever d["z"] com colchetes resultaria em KeyError, e get é a ferramenta para evitar isso.
Questão 32 | setdefault
setdefault foi chamado tanto para uma chave que já existe quanto para uma que não existe. Qual é a saída do código a seguir?
d = {"a": 1}print(d.setdefault("a", 99))print(d.setdefault("b", 99))print(d)
99 e 99 são exibidos, seguidos de {'a': 99, 'b': 99}
1 e 99 são exibidos, seguidos de {'a': 1, 'b': 99}
1 e None são exibidos, seguidos de {'a': 1, 'b': None}
1 e 99 são exibidos, seguidos de {'a': 1}
RespostaB. 1 e 99 são exibidos, seguidos de {'a': 1, 'b': 99}
setdefault apenas retorna o valor existente se a chave estiver presente, sem alterar o dicionário. Se a chave não existir, ele insere o segundo argumento como valor e retorna esse valor. Assim, a primeira chamada retorna o 1 existente e o dicionário permanece como está, e a segunda chamada insere 99 e retorna 99. Se você pensar que até o valor existente é sobrescrito, obterá ambos como 99 e, se pensar que nenhuma inserção acontece, obterá uma forma em que o dicionário não cresce. Omitir o segundo argumento faz com que o valor inserido seja None, então uma forma com None inserido é o resultado de não escrever o segundo argumento.
Questão 33 | O que in examina
Verifique o que o operador in examina em um dicionário. Qual é a saída do código a seguir?
d = {"x": 1, "y": 2}print("x" in d, 1 in d, 1 in d.values())
True False True é exibido nessa ordem
True True True é exibido nessa ordem
True False False é exibido nessa ordem
False True True é exibido nessa ordem
RespostaA. True False True é exibido nessa ordem
in aplicado a um dicionário verifica apenas as chaves. "x" é uma chave, então o resultado é True; 1 existe como valor, mas não é uma chave, então o resultado é False. Quando você quiser verificar os valores, use d.values() como alvo, que aqui dá True. Se você pensar que in também examina os valores, tudo se torna True e, se pensar que nem values() examina os valores, o último se torna False. Trocar os papéis de chave e valor leva a uma forma em que o primeiro é False. Verificar se uma chave existe antes de consultá-la com colchetes é o uso padrão.
Questão 34 | Chaves duplicadas
A mesma chave foi escrita duas vezes em um literal de dicionário. Qual é o resultado da execução do código a seguir?
d = {"a": 1, "b": 2, "a": 3}print(d)
{'a': 3, 'b': 2}
{'a': 1, 'b': 2}
{'b': 2, 'a': 3}
{'a': 3, 'b': 3}
RespostaA. {'a': 3, 'b': 2}
Um literal de dicionário constrói suas entradas em ordem, da esquerda para a direita, então, se a mesma chave aparecer duas vezes, o valor posterior sobrescreve o anterior. Isso não gera erro nem aviso. Se você pensar que permanece o que foi escrito primeiro, obterá o valor 1 para a. Além disso, um dicionário preserva a ordem de inserção (挿入した順序), e uma sobrescrita não muda a posição, então a permanece na posição em que apareceu primeiro. Portanto, a ordem das chaves também não é trocada, nem o valor de b muda como efeito colateral.
Questão 35 | Formas de construir um dicionário
Compare um dicionário construído a partir de argumentos nomeados com um construído a partir de uma sequência de pares. Qual é a saída do código a seguir?
RespostaC. True é exibido, seguido de {'x': 1, 'y': 2}
dict consegue construir um dicionário tanto a partir de argumentos nomeados (キーワード引数) quanto a partir de uma sequência de pares (chave, valor). Qualquer uma das formas de escrita produz um dicionário com o mesmo conteúdo, então a comparação é True. Se você pensar que uma forma diferente de construção produz algo diferente, a comparação se torna False. O nome de um argumento nomeado se torna, como está, a string da chave, então chave e valor nunca são trocados. Depois de passar por dict, já é um dicionário, então também não permanece como uma sequência de pares.
Questão 36 | Chaves vazias
Compare o tipo de chaves vazias com o de set(). Quais são os dois nomes de tipo exibidos quando o código a seguir é executado?
a = {}b = set()print(type(a).__name__, type(b).__name__)
dict e dict são exibidos nessa ordem
set e set são exibidos nessa ordem
dict e set são exibidos nessa ordem
set e dict são exibidos nessa ordem
RespostaC. dict e set são exibidos nessa ordem
{1, 2}, que tem elementos, torna-se um conjunto (集合), mas, quando está vazio, não é possível decidir se é um dicionário ou um conjunto. O Python trata esse caso como dicionário, então {} é um dicionário vazio. Quando você quiser um conjunto vazio, não há outra opção além de escrever set(). Se você pensar que chaves sempre significam um conjunto, obterá ambos como set, e confundir os dois leva à ordem invertida. Pensar que até set() se torna um dicionário leva a ambos como dict. Como tanto conjuntos quanto dicionários usam chaves, essa distinção é fácil de confundir.
Questão 37 | Operações de conjuntos
Foram realizadas uma interseção e uma diferença simétrica em dois conjuntos. Qual é a saída do código a seguir?
RespostaD. [3, 4] e [1, 2, 5] são exibidos nessa ordem
O e comercial (&) é a interseção (積集合), então permanecem 3 e 4, que estão nos dois. O circunflexo (^) é a diferença simétrica (対称差), que reúne os elementos que estão em apenas um dos dois, então permanecem 1 e 2, que estão só em s1, e 5, que está só em s2, enquanto os comuns 3 e 4 saem. Confundir diferença simétrica com diferença (差集合) leva a uma forma sem o 5, e trocar as duas operações inverte a ordem da saída. Confundir diferença simétrica com união (和集合) leva a uma forma que também inclui 3 e 4. A ordem de exibição de um conjunto não é fixa, então aqui o resultado é conferido ordenando-o com sorted.
Questão 38 | Remoção de duplicatas
Uma lista com duplicatas foi passada por um conjunto. Qual é a saída quando o código a seguir é executado?
data = [3, 1, 3, 2, 1, 1]print(len(set(data)), sorted(set(data)))
6 e [3, 1, 3, 2, 1, 1] são exibidos nessa ordem
6 e [1, 2, 3] são exibidos nessa ordem
3 e [3, 1, 2] são exibidos nessa ordem
3 e [1, 2, 3] são exibidos nessa ordem
RespostaD. 3 e [1, 2, 3] são exibidos nessa ordem
Passar uma lista para set remove as duplicatas (重複), deixando os 3 valores distintos 1, 2, 3, então o comprimento é 3. Passar um conjunto para sorted retorna uma nova lista ordenada em ordem crescente (昇順). Se você pensar que as duplicatas permanecem, obterá uma contagem de 6. sorted ordena pelo tamanho, e não pela ordem original de aparição, então o resultado também não fica na ordem em que os valores apareceram primeiro. A ordem de exibição do próprio conjunto não tem significado, então passe-o por sorted quando quiser ordená-lo.
Questão 39 | Uma condição para os elementos
Tentou-se acrescentar a um conjunto uma tupla e depois uma lista, uma após a outra. O que acontece quando o código a seguir é executado?
s = set()s.add((1, 2))s.add([3, 4])print(len(s))
1 é exibido, e a lista é convertida em tupla
Um TypeError é lançado, porque uma lista não pode ser colocada em um conjunto
Um ValueError é lançado, porque os tipos dos elementos não podem ser misturados
2 é exibido, e os dois elementos entram no conjunto
RespostaB. Um TypeError é lançado, porque uma lista não pode ser colocada em um conjunto
Os elementos de um conjunto, assim como as chaves de um dicionário, precisam ser hasheáveis (ハッシュ可能). Uma tupla não pode ter seu conteúdo alterado, então é hasheável e pode ser acrescentada, mas uma lista pode ter seu conteúdo alterado depois, então não é hasheável, e o resultado é um TypeError com uma mensagem sobre um tipo não hasheável (unhashable type). Supor que ambos entram leva a uma saída de 2, e supor que a lista é convertida implicitamente em tupla leva a uma saída de 1. Misturar tipos não é, em si, um problema, então o raciocínio de que ocorreria um ValueError também está errado.
Questão 40 | Três formas de extrair
Qual combinação é adequada para o que os métodos de dicionário keys, values e items retornam, respectivamente?
keys retorna pares de valores, values retorna pares de chaves, e items retorna a quantidade de itens
keys retorna pares de chaves e valores, values retorna chaves, e items retorna valores
keys retorna valores, values retorna chaves, e items retorna pares de valores
keys retorna chaves, values retorna valores, e items retorna pares de chaves e valores
RespostaD. keys retorna chaves, values retorna valores, e items retorna pares de chaves e valores
keys retorna apenas as chaves, values retorna apenas os valores, e items retorna tuplas (chave, valor) em ordem. O padrão ao percorrer um dicionário é receber duas variáveis, como em for k, v in d.items(). Trocar os papéis dos três leva a explicações como keys retornar valores. O que items retorna é uma sequência de itens, e não uma contagem, então a explicação de que ele retorna a quantidade de itens também está errada; use len quando quiser saber a quantidade. Observe que passar o próprio dicionário diretamente para for extrai as chaves.
Prática: responda às perguntas desta página
Esta é uma ferramenta de prática com perguntas em ordem aleatória (funciona quando o JavaScript está ativado). Mesmo sem ela, você pode ler todas as perguntas e explicações acima.
* As explicações são informações para fins de estudo. O conteúdo e o sistema dos exames mudam de ano para ano, por isso confira sempre os comunicados oficiais da entidade organizadora.
Esta página é uma tradução do texto original em japonês. Em caso de diferença entre a tradução e o original, prevalece a versão em japonês. Esta tradução foi feita com IA e pode conter erros.Informar um erro de traduçãoVer o original em japonês