Tengo un archivo de texto y quiero mostrar todas las palabras que contienen tanto z como x caracteres.¿Cómo mostrar todas las palabras que contienen estos caracteres?
¿Cómo puedo hacer eso?
Tengo un archivo de texto y quiero mostrar todas las palabras que contienen tanto z como x caracteres.¿Cómo mostrar todas las palabras que contienen estos caracteres?
¿Cómo puedo hacer eso?
Si no quiere tener problemas: 2
for word in file('myfile.txt').read().split():
if 'x' in word and 'z' in word:
print word
Gracias a Dios que proporcionó una respuesta que * no * usa expresiones regulares. – gotgenes
+1: Me gusta mucho esto. El único problema que puedo ver es que obtendrás cualquier puntuación que rodee tus palabras, no solo las palabras mismas. –
Es cierto que estoy usando la definición de "palabras" de python, que podría ser irracional aquí. – geoffspear
Suena como un trabajo para Regular Expressions. Lee eso y pruébalo. Si tiene problemas, actualice su pregunta y podemos ayudarlo con los detalles.
Asumiendo que tiene el archivo completo como una gran cadena en la memoria, y que la definición de una palabra es "una secuencia contigua de letras", entonces se podría hacer algo como esto:
import re
for word in re.findall(r"\w+", mystring):
if 'x' in word and 'z' in word:
print word
Me gusta esta respuesta. Es la solución más limpia. Si el rendimiento se convierte en un problema, compárelo con mi solución y elija al ganador. –
>>> import re
>>> pattern = re.compile('\b(\w*z\w*x\w*|\w*x\w*z\w*)\b')
>>> document = '''Here is some data that needs
... to be searched for words that contain both z
... and x. Blah xz zx blah jal akle asdke asdxskz
... zlkxlk blah bleh foo bar'''
>>> print pattern.findall(document)
['xz', 'zx', 'asdxskz', 'zlkxlk']
Puedo confirmar que esto funciona y es mejor que mi respuesta. Eliminaré el mío a favor de este. – Ishpeck
>>> import re
>>> print re.findall('(\w*x\w*z\w*|\w*z\w*x\w*)', 'axbzc azb axb abc axzb')
['axbzc', 'axzb']
que no conozco el funcionamiento de este generador, pero para mí t suyo es el camino:
from __future__ import print_function
import string
bookfile = '11.txt' # Alice in Wonderland
hunted = 'az' # in your case xz but there is none of those in this book
with open(bookfile) as thebook:
# read text of book and split from white space
print('\n'.join(set(word.lower().strip(string.punctuation)
for word in thebook.read().split()
if all(c in word.lower() for c in hunted))))
""" Output:
zealand
crazy
grazed
lizard's
organized
lazy
zigzag
lizard
lazily
gazing
""
"
sólo quiero señalar cómo de mano dura algunas de estas expresiones regulares puede ser, en comparación con la sencilla string methods-based solution provided by Wooble.
Hagamos algunos tiempos, ¿de acuerdo?
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import timeit
import re
import sys
WORD_RE_COMPILED = re.compile(r'\w+')
Z_RE_COMPILED = re.compile(r'(\b\w*z\w*\b)')
XZ_RE_COMPILED = re.compile(r'\b(\w*z\w*x\w*|\w*x\w*z\w*)\b')
##########################
# Tim Pietzcker's solution
# https://stackoverflow.com/questions/3962846/how-to-display-all-words-that-contain-these-characters/3962876#3962876
#
def xz_re_word_find(text):
for word in re.findall(r'\w+', text):
if 'x' in word and 'z' in word:
print word
# Tim's solution, compiled
def xz_re_word_compiled_find(text):
pattern = re.compile(r'\w+')
for word in pattern.findall(text):
if 'x' in word and 'z' in word:
print word
# Tim's solution, with the RE pre-compiled so compilation doesn't get
# included in the search time
def xz_re_word_precompiled_find(text):
for word in WORD_RE_COMPILED.findall(text):
if 'x' in word and 'z' in word:
print word
################################
# Steven Rumbalski's solution #1
# (provided in the comment)
# https://stackoverflow.com/questions/3962846/how-to-display-all-words-that-contain-these-characters/3963285#3963285
def xz_re_z_find(text):
for word in re.findall(r'(\b\w*z\w*\b)', text):
if 'x' in word:
print word
# Steven's solution #1 compiled
def xz_re_z_compiled_find(text):
pattern = re.compile(r'(\b\w*z\w*\b)')
for word in pattern.findall(text):
if 'x' in word:
print word
# Steven's solution #1 with the RE pre-compiled
def xz_re_z_precompiled_find(text):
for word in Z_RE_COMPILED.findall(text):
if 'x' in word:
print word
################################
# Steven Rumbalski's solution #2
# https://stackoverflow.com/questions/3962846/how-to-display-all-words-that-contain-these-characters/3962934#3962934
def xz_re_xz_find(text):
for word in re.findall(r'\b(\w*z\w*x\w*|\w*x\w*z\w*)\b', text):
print word
# Steven's solution #2 compiled
def xz_re_xz_compiled_find(text):
pattern = re.compile(r'\b(\w*z\w*x\w*|\w*x\w*z\w*)\b')
for word in pattern.findall(text):
print word
# Steven's solution #2 pre-compiled
def xz_re_xz_precompiled_find(text):
for word in XZ_RE_COMPILED.findall(text):
print word
#################################
# Wooble's simple string solution
def xz_str_find(text):
for word in text.split():
if 'x' in word and 'z' in word:
print word
functions = [
'xz_re_word_find',
'xz_re_word_compiled_find',
'xz_re_word_precompiled_find',
'xz_re_z_find',
'xz_re_z_compiled_find',
'xz_re_z_precompiled_find',
'xz_re_xz_find',
'xz_re_xz_compiled_find',
'xz_re_xz_precompiled_find',
'xz_str_find'
]
import_stuff = functions + [
'text',
'WORD_RE_COMPILED',
'Z_RE_COMPILED',
'XZ_RE_COMPILED'
]
if __name__ == '__main__':
text = open(sys.argv[1]).read()
timings = {}
setup = 'from __main__ import ' + ','.join(import_stuff)
for func in functions:
statement = func + '(text)'
timer = timeit.Timer(statement, setup)
min_time = min(timer.repeat(3, 10))
timings[func] = min_time
for func in functions:
print func + ":", timings[func], "seconds"
La ejecución de este script en un plaintext copy of Moby Dick obtenida de Project Gutenberg, en Python 2.6, consigo los siguientes tiempos:
xz_re_word_find: 1.21829485893 seconds
xz_re_word_compiled_find: 1.42398715019 seconds
xz_re_word_precompiled_find: 1.40110301971 seconds
xz_re_z_find: 0.680151939392 seconds
xz_re_z_compiled_find: 0.673038005829 seconds
xz_re_z_precompiled_find: 0.673489093781 seconds
xz_re_xz_find: 1.11700701714 seconds
xz_re_xz_compiled_find: 1.12773990631 seconds
xz_re_xz_precompiled_find: 1.13285303116 seconds
xz_str_find: 0.590088844299 seconds
En Python 3.1 (después de usar 2to3 para fijar las declaraciones de impresión), consigo los siguientes tiempos:
xz_re_word_find: 2.36110496521 seconds
xz_re_word_compiled_find: 2.34727501869 seconds
xz_re_word_precompiled_find: 2.32607793808 seconds
xz_re_z_find: 1.32204890251 seconds
xz_re_z_compiled_find: 1.34104800224 seconds
xz_re_z_precompiled_find: 1.34424304962 seconds
xz_re_xz_find: 2.33851099014 seconds
xz_re_xz_compiled_find: 2.29653286934 seconds
xz_re_xz_precompiled_find: 2.32416701317 seconds
xz_str_find: 0.656699895859 seconds
podemos ver que las funciones regulares basadas en expresiones tienden a tomar el doble de tiempo para ejecutarse como la strin g función basada en métodos en Python 2.6, y más de 3 veces más en Python 3. La diferencia de tiempo es trivial para el análisis único (nadie va a perder esos milisegundos), pero para los casos donde la función debe ser llamada muchas veces, el enfoque basado en métodos de cadena es tanto más simple como más rápido.
Yo también prefiero los métodos de cadena. Pero, aquí hay un nitpick.Cambié la definición de zx_re_find (texto) y es 4 veces más rápido que el método de cadena pura: def zx_re_find (texto): pat = re.compile ('(\ b \ w * z \ w * \ b)') para palabra en pat.findall (texto): si 'x' en palabra: palabra de impresión –
@Steven He actualizado mi respuesta para incluir incluir su solución sugerida en el comentario, y la solución que proporcionó como respuesta, y lo hice no obtiene el rendimiento 4X por ninguna expresión regular en comparación con el método de cadena. Para mí, las soluciones de RE todavía están detrás. ¿Qué texto usaste para probar tu desempeño? – gotgenes
@gotgenes Utilicé la misma copia de texto claro de Moby Dick. Utilicé Python 2.7 en Windows XP (hmm ... olvidé el chip en mi portátil de trabajo). Recuerdo los primeros 3 dígitos de los tiempos 0.311 para la secuencia y 0.088 para la expresión regular (no realmente 4x, pero cerca). Sostengo que si los requisitos fueran más complicados, la expresión regular ganaría en simplicidad y rendimiento. –
¿Dónde está el problema exacto? ¿Qué has intentado hasta ahora? –
No sé cómo analizar el archivo de texto :) – xRobot
Las expresiones regulares son el rey cuando se trata de análisis de texto. Mira la solución de Ishpeck. – Squirrelsama