Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Cargar el clipboard en una lista o a un diccionario
#1
Estimados todos. Intento encontrar alguna opción que me permita cargar los datos del clipboard a una tabla o a un diccionario Python. Con el módulo Tk, se podría hacer esto?.
Al utilizar el comando "clip_text = root.clipboard_get()" qué obtengo, ¿una tabla? ¿un texto con todas las líneas y valores de las dos columnas?
Saludos cordiales
Responder
#2
Hola, ¿cómo estás?

Por defecto la función clipboard_get retorna el contenido del portapapeles como una cadena. Eso no quiere decir que no pueda ser analizado y restructurado como un diccionario o alguna otra colección de Python. ¿Qué es exactamente lo que esperas que haya en el portapapeles? ¿Podrías dejar un ejemplo?

Saludos
¡No te pierdas nuestro curso oficial en Udemy para aprender Python, bases de datos SQL, orientación a objetos, tkinter y mucho más!

También ofrecemos consultoría profesional de desarrollo en Python para personas y empresas.
Responder
#3
clipboard_get() parece que devuelve siempre una string, según las pruebas que he verificado, lo que hace dificil su manipulación:

edito:
Hay una libreria llamada pyperclip, pero solo maneja texto plano:
https://pypi.python.org/pypi/pyperclip

Código:
from tkinter import *

root = Tk()
# evitamos que se muestre la ventana
root.withdraw()
mi_cadena = "Esto es mi cadena"
root.clipboard_clear()
# envio mi_cadena al clipboard
root.clipboard_append(mi_cadena)
# recogemos el texto del clipboard
clip_texto = root.clipboard_get()
print(clip_texto)
print(type(clip_texto))
"""
La salida será:
Esto es mi cadena
<class 'str'>
"""
# ahora probamos con una tupla
mi_tupla = 'Esta ', 'es ', 'mi ','tupla',
print(type(mi_tupla))
root.clipboard_clear()
# envio mi_tupla al clipboard
root.clipboard_append(mi_tupla)
# recogemos el texto del clipboard
clip_tupla = root.clipboard_get()
print(clip_tupla)
print(type(clip_tupla))
"""
La salida de este pedazo da como salida:
<class 'tuple'>
{Esta } {es } {mi } tupla
<class 'str'>
"""
# parece que aunque asignemos una tupla, clipboard_get()
# retorna una cadena donde cada elemento de la tupla lo encierra
# entre llaves, pero no es un diccionaro
# print(clip_tupla[0]) nos retorna una simple {

# ahora probamos con una lista:
mi_lista = ['Esta ', 'es ', 'mi ','lista']
print(type(mi_lista))
root.clipboard_clear()
# envio mi_lista al clipboard
root.clipboard_append(mi_lista)
# recogemos el texto del clipboard
clip_lista = root.clipboard_get()
print(clip_lista)
print(type(clip_lista))
"""
con la lista pasa lo mismo:
<class 'list'>
{Esta } {es } {mi } lista
<class 'str'>
"""

# por ultimo un diccionario
mi_diccionario = {'1':'Este ', '2':'es ', '3':'mi ', '4':'diccionario'}
print(type(mi_diccionario))
root.clipboard_clear()
# envio mi_diccionario al clipboard
root.clipboard_append(mi_diccionario)
# recogemos el texto del clipboard
clip_diccionario = root.clipboard_get()
print(clip_diccionario)
print(type(clip_diccionario))
"""
aqii tambien retorna una str:
<class 'dict'>
{'1': 'Este ', '2': 'es ', '3': 'mi ', '4': 'diccionario'}
<class 'str'>
"""
# ahora añado al clipboar las cuatro variables
root.clipboard_clear()
root.clipboard_append(mi_cadena)
root.clipboard_append(mi_tupla)
root.clipboard_append(mi_lista)
root.clipboard_append(mi_diccionario)
clip_resumen = root.clipboard_get()
print(clip_resumen)
print(type(clip_resumen))
"""
me suelta esto del tirón:
Esto es mi cadena{Esta } {es } {mi } tupla{Esta } {es } {mi } lista{'1': 'Este ', '2': 'es ', '3': 'mi ', '4': 'diccionario'}
<class 'str'>
"""
Responder
#4
Gracias a todos por la ayuda.
Tengo un Libro Excel con muchas hojas. En cada hoja, entre otras muchas cosas, hay un rango de datos (dos columnas: fecha y número)(pueden llegar a ser del orden de 3000 filas), que quiero capturar en Python para analizarlos.  Intentar leerlos directamente de la hoja con por ejemplo openpyxl, me resulta complicado y lento.

Por ello he pensado que si consigo desarrollar un script que, si tengo algo en el portapapeles, al ejecutarlo lo importa a una tabla o a un diccionario, ésta opción me resultaría mucho más eficiente. De ahí mi pregunta.
¿Se os ocurre alguna opción?.
Saludos cordiales
Responder
#5
Estimados todos, con Tk consigo un strig.
# !/usr/bin/env python

# -*- coding: utf-8 -*-

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk
root = tk.Tk()

# text from clipboard
clip_text = root.clipboard_get()
#print(clip_text)  # --> Donnerwetter
print (clip_text)
print (type(clip_text))

como este
20/07/17    2,00
19/07/17    177,90
18/07/17    177,64
17/07/17    177,50
14/07/17    177,36
13/07/17    176,96
12/07/17    177,06
11/07/17    177,90
10/07/17    177,90
7/07/17    178,13
6/07/17    178,20
5/07/17    178,01
4/07/17    177,71
3/07/17    177,92
30/06/17    178,90
29/06/17    177,88
28/06/17    177,12
27/06/17    177,17
..............................
<type 'str'>

Como podéis ver, bastante complicado para pasarlo a una lista o a un diccionario. ¿?
Saludos cordiales
Responder
#6
hola,

si te sale, tal como muestras, teoricamente al final encontrarás un '\r\n' (windows), '\n' (linux), '\r' (MacOS).
Si es asi puedes hacer algo asi como esto:

cadena1 = cadena.split('\n')

ahora cada lemento será un  cadena[0] = '20/07/17    2,00' ...... cadena[n] = '27/06/17    177,17'; esto es cada elemento de la lista es una cadena que se puede dividir por el espacio. Por lo tanto cada elemento lo convertimos, p.ej. en una tupla (hacerlo en bucle):

elemento_0 = cadena[0].split('un espacio ')
tupla_0 = (elemento_0[0], elemento_0[1])

lista.append(tupla_0)

y asi ya tendrías los datos estructurados.


De todas maneras, creo que lo que buscas es la libreria Pandas, la cual es una libreria de palabras mayores. Hay libros completos sobre esta libreria. Puedes encontrarlos "googleando"

Creo que pandas puede importar directamente las hojas de calculo comerciales que mencionas, y montar una tabla (DataFrame en pandas). Junto con otras librerias, maneja regresiones, correlaciones, varianzas, teorema de Bayes, etc...

edito:
acabo de revisar unos apuntes que me pasaron hace tiempo, y creo que esto cumple tus expectativas:




Código:
import pandas as pd
pd.read_clipboard()            # Si hemos seleccionado las cabeceras de la hoja de calculo
pd.read_clipboard(header=None) # Si no las hemos seleccionado
... hay mas, pero por ser breve


y lo que nos devuelve pandas es una tabla de datos (DataFrame)

sobre excel en concreto : http://pandas.pydata.org/pandas-docs/sta...dataframes

pandas suele ir compañada de una o varias de estas librerias:

Numpy: http://www.numpy.org/

SoiPy: https://www.scipy.org/

StatsModels: http://www.statsmodels.org/stable/index.html

scikit-learn : http://scikit-learn.org/stable/

PyMC :https://pymc-devs.github.io/pymc/


Visualización gráfica:

matplotlib : https://matplotlib.org/

seaborn : https://seaborn.pydata.org/
Responder
#7
Gracias Calvicius.
He encontrado este tutorial, y estoy buscando en el nuevas opciones.
https://www.datacamp.com/community/tutor...gs.aw3jPF4
No descarto intentarlo con tu propuesta, aunque me plantea el problema de que, como puedes ver en la estructura de los datos de salida del script, no es uniforme en cuanto a espacios entre la fecha y los datos, ni en cuanto a la longitud de la fecha.
Saludos cordiales
Responder
#8
(11-09-2017, 08:02 AM)efueyo escribió: Gracias Calvicius.
He encontrado este tutorial, y estoy buscando en el nuevas opciones.
https://www.datacamp.com/community/tutor...gs.aw3jPF4
No descarto intentarlo con tu propuesta, aunque me plantea el problema de que, como puedes ver en la estructura de los datos de salida del script, no es uniforme en cuanto a espacios entre la fecha y los datos, ni en cuanto a la longitud de la fecha.
Saludos cordiales

de nada hombre.

Voy a tomar estas dos lineas de tu ejemplo:
12/07/17    177,06 (4 espacios)
7/07/17   178,13 (3 espacios)

1.- Lo de los espacios...

hacemos un elem.split(' ') --> 1 espacio.
supongamos que lo hacemos sobre la cadena con 4 espacios:
>>> cadena = "12/07/17    177,06"
>>> elems = cadena.split(' ')
>>> elems
['12/07/17', '', '', '', '177,06']

como vemos se han creado tres elementos vacíos en la lista. Lo cual ya es fácil, bien con elems.remove("") o con elems.pop(indice)

Edito:
Te pongo el ejemplo completo (pero antes comprueba que sean espacios y no tabuladores '\t', por ejemplo):

Código:
cadena = "12/07/17    177,06"
elems = cadena.split(' ')

#este es el modelo más caro en tiempo para una lista larga
#el costo en el peor de los casos es el num. de elementos elevado al cuadrado
elementos_validos = []

for i in range(len(elems)):
   if elems[i] != "":
       elementos_validos.append(elems[i])
       
print(elementos_validos)

# mas rapido para muchos datos es:
# podemos aprovechar que los diccionarios no admiten claves duplicadas
# la pega es que no tiene por qué mantener el orden original de los elementos
# el coste es el num. de elementos
validos_dict = dict.fromkeys(elems).keys()
print(validos_dict)

# ahora tenemos un solo elemento cuya clave es "". Lo eliminamos
lista_eliminar = list(validos_dict)
print(lista_eliminar)   # con el elemento vacio
lista_eliminar.remove('')
print(lista_eliminar)   # sin el elemento vacio


# lo mismo que con diccionarios, tambien se puede hacer con conjuntos
# la pega es la misma que con diccionarios
# el coste es el num. de elementos

# list(set(lista_original - en este caso elems))


2.- Lo de las fechas...

import datetime
mi_fecha = "12/07/17"

datetime.datetime.strptime(mi_fecha', '%d/%m/%y').date()

y ya tenemos la cadena fecha como un objeto fecha.
Responder
#9
Calvicius, He visto que con Pandas, puedo conseguir fácilmente un dataframe, en este ejemplo, denominado df1.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Import pandas
import pandas as pd
# Assign spreadsheet filename to `file`
file = 'pruebas.xlsx'
# Load spreadsheet
xl = pd.ExcelFile(file)
# Print the sheet names
print(xl.sheet_names)
# Load a sheet into a DataFrame by name: df1
df1 = xl.parse('Hoja2')
print (df1)

El siguiente paso, que no debe ser muy difícil, sería pasarlo a diccionario  utilizando la función pandas:
DataFrame.to_dict([orient])

Esto serviría para mi propósito, pero no sé qué debo poner en "orient".

Agradeceré tu ayuda, si es que lo sabes.
Saludos cordiales
Responder
#10
sobre DataFrame.to_dict([orient])

te remito a la página oficial:

https://pandas.pydata.org/pandas-docs/st..._dict.html

que dice:

pandas.DataFrame.to_dict(orient='dict')

Convert DataFrame to dictionary.

 Parameters:
orient : str {‘dict’, ‘list’, ‘series’, ‘split’, ‘records’, ‘index’}
Cita:
  • dict (default) : dict like {column -> {index -> value}}
  • list : dict like {column -> [values]}
  • series : dict like {column -> Series(values)}
  • split : dict like {index -> [index], columns -> [columns], data -> [values]}
  • records : list like [{column -> value}, ... , {column -> value}]
  • index : dict like {index -> {column -> value}}
    New in version 0.17.0.
Abbreviations are allowed. s indicates series and sp indicates split.
Returns:
result : dict like {column -> {index -> value}}

que segun interpreto, es el tipo de datos que vas a poner en el diccionario. orient='list' --> si es una lista, etc...
Los diccionarios tienen clave unica. imaginemos una tabla (df) tal que asi:

      id     valor
0    0      99.9
1    1      55.5
2    2      77.7

dataframe.set_index('id').to_dict()

y si la tabla tuviese un solo valor:


dataframe.set_index('id')['valor'].to_dict()

pero tienes que tener en cuenta que en tu ejemplo pueden haber datos duplicados, los cuales en este caso se perderían los duplicados. Quizas te interese pasarlo a una lista de tuplas, siendo cada tupla una fila o columna (segun elijas)

dataframe = pandas.DataFrame([[1,2,3],[3,4,5]])
resultado_lista = dataframe.values.tolist()

o bien:

resultado = df.values

o bien:

df.values.flatten()

etc...

Nota: esta libreria hay que leerla en serio. Mira aqui: Libros sobre Pandas
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)