From: keyboard
Subject: put list to hash table - did I do it right?
Date: 
Message-ID: <f4cd5bea-d013-4267-a265-bdce893e22ad@56g2000hsm.googlegroups.com>
Hi,

I have a list in a file like

(
a °¡
a °¢
a ºÇ
a ß¹
a àÄ
a ëç
a ï¹
a åH
aes …
ai °®
ai °«
ai °¤
ai °¥
ai °­
ai °©
ai °¬
ai °¦
ai °§
ai °ª
ai °¯
...
)

What I want to do is to put this list in a table such that when I
search the Chinese, it output the Pinyin.

I did the following

(defvar *Hanzi-Pinyin-pair* nil)
(defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))

(with-open-file (is #P"GBK-1.txt" :direction :input)
  (setf *Hanzi-Pinyin-pair* (read is)))

(let ((n (length *Hanzi-Pinyin-pair*)))
  (loop repeat (/ n 2)
    for i = 0 then (+ 2 i)
    do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))

(defun find-pinyin (c)
  "input Chinese C to find its PINYIN"
  (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
pair*)))

but why *hash-Hanzi-Pinyin-pair has no value?

Thank you.

From: D Herring
Subject: Re: put list to hash table - did I do it right?
Date: 
Message-ID: <qJadnfCOkoRv9K_VnZ2dnUVZ_r6rnZ2d@comcast.com>
keyboard wrote:
> Hi,
> 
> I have a list in a file like
> 
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �H
> aes ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
> 
> What I want to do is to put this list in a table such that when I
> search the Chinese, it 	output the Pinyin.
> 
> I did the following
> 
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
> 
> (with-open-file (is #P"GBK-1.txt" :direction :input)
>   (setf *Hanzi-Pinyin-pair* (read is)))
> 
> (let ((n (length *Hanzi-Pinyin-pair*)))
>   (loop repeat (/ n 2)
>     for i = 0 then (+ 2 i)
>     do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))
> 
> (defun find-pinyin (c)
>   "input Chinese C to find its PINYIN"
>   (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
> 
> but why *hash-Hanzi-Pinyin-pair has no value?

Dunno.  I tried your example, but (with my i18n settings) slime
croaked on the final gethash; so I was unable to use the hashtable,
but it seemed to have the right members.  When I substituted integers
for the Chinese characters, everything worked as expected.

Maybe your lisp doesn't treat Hanzi as EQ?  Try this:
(defvar *hash-Hanzi-Pinyin-pair* (make-hash-table :test 'equal))

Also, the SBCL reader is reading the Hanzi as symbols, not characters.
 If yours does the same, then call (find-pinyin |��|) instead of
(find-pinyin ��).

FWIW, traversing lists by calling (elt list index) is slow; elt finds
each element by starting at the head and counting to N.  Here's a few
alternatives

(defparameter *h* (make-hash-table))
(defparameter *l* '((1 2) (3 4) (5 6)))
(mapc (lambda (pair)
	(setf (gethash (car pair) *h*) (cadr pair)))
      *l*)
;; or
(dolist (pair *l*)
  (setf (gethash (car pair) *h*) (cadr pair)))
;; or
(loop for (key val) in *l*
      do (setf (gethash key *h*) val))

Or if your source list is a flat set of key/value pairs, here's
another way to walk the list:
(defparameter *h* (make-hash-table))
(loop for key = '(1 2 3 4 5 6) then (cdr val)
      for val = (cdr key)
      while val
      do (setf (gethash (car key) *h*)
	       (car val)))

And I'm sure there are better alternatives.

- Daniel
From: Ken Tilton
Subject: Re: put list to hash table - did I do it right?
Date: 
Message-ID: <4832b088$0$15173$607ed4bc@cv.net>
keyboard wrote:
> Hi,
> 
> I have a list in a file like
> 
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �H
> aes ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
> 
> What I want to do is to put this list in a table such that when I
> search the Chinese, it output the Pinyin.
> 
> I did the following
> 
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
> 
> (with-open-file (is #P"GBK-1.txt" :direction :input)
>   (setf *Hanzi-Pinyin-pair* (read is)))
> 
> (let ((n (length *Hanzi-Pinyin-pair*)))
>   (loop repeat (/ n 2)
>     for i = 0 then (+ 2 i)
>     do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))

FYI:

   (loop for (hanzi pinyin) on *hanzi-pinyin-pair* by #'cddr
         do (setf (gethash hanzi etc) pinyin))

> 
> (defun find-pinyin (c)
>   "input Chinese C to find its PINYIN"
>   (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
> 
> but why *hash-Hanzi-Pinyin-pair has no value?

Show us how you know it has no value. READ would produce symbols (which
would become the hash key and value) and you might be looking for strings.

We do not know because you stopped short of providing a full report of
your problem. It is a PITA, I know, but you really have to dump
everything into problem reports to avoid a lot of confusion and lectures
like this. :)

kt


-- 
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
ECLM rant:
http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
ECLM talk:
http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en
From: maximinus
Subject: Re: put list to hash table - did I do it right?
Date: 
Message-ID: <f878ab51-32ab-4693-adac-3d567f73f278@n1g2000prb.googlegroups.com>
On May 20, 7:05 pm, Ken Tilton <···········@optonline.net> wrote:
> keyboard wrote:
> > Hi,
>
> > I have a list in a file like
>
> > (
> > a °¡
> > a °¢
> > a ºÇ
> > a ß¹
> > a àÄ
> > a ëç
> > a ï¹
> > a åH
> > aes …
> > ai °®
> > ai °«
> > ai °¤
> > ai °¥
> > ai °­
> > ai °©
> > ai °¬
> > ai °¦
> > ai °§
> > ai °ª
> > ai °¯
> > ...
> > )
>
> > What I want to do is to put this list in a table such that when I
> > search the Chinese, it output the Pinyin.
>
> > I did the following
>
> > (defvar *Hanzi-Pinyin-pair* nil)
> > (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
>
> > (with-open-file (is #P"GBK-1.txt" :direction :input)
> >   (setf *Hanzi-Pinyin-pair* (read is)))
>
> > (let ((n (length *Hanzi-Pinyin-pair*)))
> >   (loop repeat (/ n 2)
> >     for i = 0 then (+ 2 i)
> >     do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> > Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))
>
> FYI:
>
>    (loop for (hanzi pinyin) on *hanzi-pinyin-pair* by #'cddr
>          do (setf (gethash hanzi etc) pinyin))
>
>
>
> > (defun find-pinyin (c)
> >   "input Chinese C to find its PINYIN"
> >   (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> > pair*)))
>
> > but why *hash-Hanzi-Pinyin-pair has no value?
>
> Show us how you know it has no value. READ would produce symbols (which
> would become the hash key and value) and you might be looking for strings.
>
> We do not know because you stopped short of providing a full report of
> your problem. It is a PITA, I know, but you really have to dump
> everything into problem reports to avoid a lot of confusion and lectures
> like this. :)
>
> kt
>
> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
> ECLM rant:http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
> ECLM talk:http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en

Holy s**t.

Someone else who both

1: Programs Lisp
2: And studies Chinese

I live in Harbin, China, and I program Lisp, so I had to comment on
this. Other people have given you some code info, so I won't comment
on that; but your least seems a little wrong, since 'aes' (in your
list) is not real Pinyin.
Also, how do you store tone information?

Anyhow, feel free to write to me at maximinus AT_THIS_ADDRESS gmail.com
From: Rainer Joswig
Subject: Re: put list to hash table - did I do it right?
Date: 
Message-ID: <joswig-0F5B10.07172620052008@news-europe.giganews.com>
In article 
<····································@56g2000hsm.googlegroups.com>,
 keyboard <···········@gmail.com> wrote:

> Hi,
> 
> I have a list in a file like
> 
> (
> a ��
> a ��
> a ��
> a ߹
> a ��
> a ��
> a �
> a �
> aes ?
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ai ��
> ...
> )
> 
> What I want to do is to put this list in a table such that when I
> search the Chinese, it output the Pinyin.

What Lisp implementation are you using?

> 
> I did the following
> 
> (defvar *Hanzi-Pinyin-pair* nil)
> (defvar *hash-Hanzi-Pinyin-pair* (make-hash-table))
> 
> (with-open-file (is #P"GBK-1.txt" :direction :input)
>   (setf *Hanzi-Pinyin-pair* (read is)))

What did it read?

> (let ((n (length *Hanzi-Pinyin-pair*)))
>   (loop repeat (/ n 2)
>     for i = 0 then (+ 2 i)
>     do (setf (gethash (elt *Hanzi-Pinyin-pair* (+ i 1)) *hash-Hanzi-
> Pinyin-pair*) (elt *Hanzi-Pinyin-pair* i))))

Side note: above is really a horrible way to iterate over a list.
A list usually should not accessed with ELT from a LOOP.
Instead of iterating ONCE over a list, you will do it MULTIPLE
times. Lists are not arrays Common Lisp, so random access
to list elements is NOT of complexity o(1).

Use something like
CL-USER 28 : 1 > (loop for (s1 s2) on '(a b c d) by #'cddr do (print (list s1 s2)))

(A B) 
(C D) 
NIL

> 
> (defun find-pinyin (c)
>   "input Chinese C to find its PINYIN"
>   (format t "~A~ has the PINYIN ~A~%." c (gethash c *hash-Hanzi-Pinyin-
> pair*)))
> 
> but why *hash-Hanzi-Pinyin-pair has no value?

How do you call this function?

Note that your Lisp (when it deals with correctly with the above file)
read a list of symbols (not characters). When you use GETHASH later
make sure that you ask for a symbol (and not a character).

> 
> Thank you.

-- 
http://lispm.dyndns.org/